def generate_summary_direct()

in tools/smol_tools/demo_tkinter.py [0:0]


    def generate_summary_direct(self, text):
        summary_popup = tk.Toplevel(self.root)
        summary_popup.withdraw()  # Hide the window initially
        self.active_popups.append(summary_popup)
        summary_popup.title("Summary Chat")
        summary_popup.configure(bg='#f6f8fa')
        
        # Set minimum window size
        summary_popup.minsize(600, 600)
        
        # Main container
        container = tk.Frame(summary_popup, bg='#f6f8fa')
        container.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # Chat display area (top)
        chat_frame = tk.Frame(
            container,
            bg='white',
            highlightbackground='#e1e4e8',
            highlightthickness=1,
            bd=0,
            relief=tk.FLAT
        )
        chat_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        # Add chat display with scrollbar
        chat_display = tk.Text(
            chat_frame, 
            wrap=tk.WORD,
            borderwidth=0,
            highlightthickness=0,
            bg='white',
            fg='#24292e',
            font=('Segoe UI', 12),
            padx=15,
            pady=12
        )
        scrollbar = tk.Scrollbar(chat_frame, command=chat_display.yview)
        chat_display.configure(yscrollcommand=scrollbar.set)
        
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        chat_display.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # Configure text tags
        chat_display.tag_configure("assistant_name", foreground="#E57373", font=('Segoe UI', 12, 'bold'))
        chat_display.tag_configure("user_name", foreground="#7986CB", font=('Segoe UI', 12, 'bold'))
        chat_display.config(state='disabled')
        
        # Input area (bottom)
        input_container = tk.Frame(
            container,
            bg='white',
            highlightbackground='#e1e4e8',
            highlightthickness=1,
            bd=0,
            relief=tk.FLAT
        )
        input_container.pack(fill=tk.X)
        
        # Text input
        chat_input = tk.Text(
            input_container, 
            height=3, 
            wrap=tk.WORD,
            borderwidth=0,
            highlightthickness=0,
            bg='white',
            fg='#24292e',
            font=('Segoe UI', 12),
            padx=15,
            pady=12,
            insertwidth=2,  # Width of cursor
            insertbackground='#0066FF',  # Color of cursor matching our theme
            insertofftime=500,  # Cursor blink off time in milliseconds
            insertontime=500   # Cursor blink on time in milliseconds
        )
        chat_input.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # Send button
        send_btn = Button(
            input_container,
            text="Ask Question",
            command=lambda: self.process_summary_question(
                text, chat_input.get("1.0", "end-1c").strip(),
                chat_display, chat_input
            ),
            font=('Segoe UI', 12),
            bg='#0066FF',
            fg='white',
            activebackground='#0052CC',
            activeforeground='white',
            borderless=True,
            focuscolor='',
            height=32,
            padx=15
        )
        send_btn.pack(side=tk.RIGHT, padx=15, pady=8)
        
        # Bind Enter key
        chat_input.bind("<Return>", lambda e: [
            self.process_summary_question(
                text, chat_input.get("1.0", "end-1c").strip(),
                chat_display, chat_input
            ),
            "break"
        ][1])
        
        # Display initial summary request
        preview = text[:100] + "..." if len(text) > 100 else text
        self.update_summary_chat(chat_display, self.username, f"Please summarize this text: {preview}")
        
        # Position window
        summary_popup.update_idletasks()
        popup_width = 600
        popup_height = 600
        
        # Get mouse position and screen dimensions
        mouse_x = self.root.winfo_pointerx()
        mouse_y = self.root.winfo_pointery()
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        
        # Calculate position
        x = min(max(mouse_x - popup_width//2, 0), screen_width - popup_width)
        y = min(max(mouse_y - popup_height//2, 0), screen_height - popup_height)
        
        summary_popup.geometry(f"{popup_width}x{popup_height}+{x}+{y}")
        summary_popup.deiconify()
        
        def summarize(input_text):
            try:
                # First message from the model
                self.root.after(0, lambda: self.update_summary_chat(
                    chat_display, self.summarizer.name, ""))
                
                current_response = ""
                for output in self.summarizer.process(input_text):
                    # Only send the new part of the response
                    if output.startswith(current_response):
                        new_text = output[len(current_response):]
                        if new_text:  # Only update if there's new text
                            current_response = output
                            self.root.after(0, lambda t=new_text: chat_display.config(state='normal') or 
                                chat_display.insert("end-1c", t) or 
                                chat_display.config(state='disabled'))
            except Exception as e:
                print(e)
        
        threading.Thread(target=lambda: summarize(text), daemon=True).start()