Skip to content

Conversation

@Mirrowel
Copy link
Owner

@Mirrowel Mirrowel commented Dec 8, 2025

Summary

  • Adds a new GUI application for visually configuring model ignore/whitelist rules per provider
  • Implements high-performance virtual lists using canvas-based rendering for instant loading of 200+ models
  • Provides synchronized dual-pane view showing all fetched models alongside their filtered status with color-coded rules
    Features
    Core Functionality
  • Provider Selection: Dropdown to switch between available providers with automatic model fetching
  • Ignore Rules: Pattern-based rules (supports wildcards) to exclude models from availability
  • Whitelist Rules: Pattern-based rules to explicitly include models, overriding ignore rules
  • Real-time Preview: Typing in rule input fields highlights affected models before committing
  • Rule-Model Linking: Click a model to highlight the rule affecting it; click a rule to highlight all affected models
    Performance Optimizations
  • Virtual Model Lists: Canvas-based rendering that only draws visible items, enabling instant loading even with hundreds of models
  • Virtual Rule Lists: Same optimization applied to rule display
  • Debounced Updates: Rule changes and preview updates are debounced to prevent UI lag
  • Background Prefetching: Models for all providers are fetched in background after initial load
    UI/UX
  • Synchronized Scrolling: Left (all models) and right (filtered status) lists scroll together
  • Responsive Layout: 3:1 height ratio between model lists and rule panels using grid weights
  • Color-Coded Rules: Each rule gets a unique color; affected models display in that color
  • Tooltips: Hover over rules to see list of affected models
  • Keyboard Shortcuts: Ctrl+S (save), Ctrl+R (refresh), Ctrl+F (search), F1 (help), Escape (clear)
  • Context Menu: Right-click models to add to ignore/whitelist or copy name
  • Unsaved Changes Tracking: Visual indicator and confirmation dialog when switching providers or closing
    Technical Details
  • Dark mode only (matches application theme)
  • Minimum window size: 600x600px
  • Persists rules to .env file using existing IGNORE_MODELS_* and WHITELIST_MODELS_* format
  • Built with CustomTkinter for modern appearance
    Screenshots
    Add screenshots showing the GUI with models loaded, rules applied, and color-coded status
    Testing
  • Verified with providers returning 200+ models
  • Tested resize behavior at various window sizes
  • Confirmed rule persistence to .env file

Important

Introduces a new GUI for managing model ignore/whitelist rules, enhancing user experience with visual configuration and performance optimizations.

  • Behavior:
    • Adds model_filter_gui.py for visual configuration of model ignore/whitelist rules per provider.
    • Integrates GUI launch option in settings_tool.py.
    • GUI supports pattern-based ignore/whitelist rules with real-time preview and rule-model linking.
  • Performance:
    • Implements virtual lists for models and rules in model_filter_gui.py for efficient rendering.
    • Debounced updates and background prefetching to enhance performance.
  • UI/UX:
    • Dual-pane view with synchronized scrolling and color-coded rules.
    • Tooltips, context menus, and keyboard shortcuts for improved usability.
    • Dark mode only, with a minimum window size of 600x600px.
  • Misc:
    • Updates requirements.txt to include customtkinter for GUI support.
    • Adds documentation for the new GUI in DOCUMENTATION.md.

This description was created by Ellipsis for 7f1d2c1. You can customize this summary. It will automatically update as commits are pushed.

Introduces a comprehensive CustomTkinter-based GUI application for managing model ignore/whitelist rules per provider, accessible from the settings tool.

- Created model_filter_gui.py with full-featured visual editor (2600+ lines)
- Implemented dual synchronized model lists showing unfiltered and filtered states
- Added color-coded rule chips with visual association to affected models
- Real-time pattern preview as users type filter rules
- Interactive click/right-click functionality for model-rule relationships
- Context menus for quick actions (add to ignore/whitelist, copy names)
- Comprehensive help documentation with keyboard shortcuts
- Unsaved changes detection with save/discard/cancel workflow
- Background prefetching of models for all providers to improve responsiveness
- Integration with settings tool as menu option #6

The GUI provides pattern matching with exact match, prefix wildcard (*), and match-all support. Whitelist rules take priority over ignore rules. All changes are persisted to .env file using IGNORE_MODELS_* and WHITELIST_MODELS_* variables.
Replace widget-based model lists with canvas-based virtual rendering to drastically improve performance with large model lists (1000+ models).

- Add caching layer in FilterEngine with automatic invalidation on rule changes
- Implement VirtualModelList component that only renders visible rows
- Replace SyncModelListPanel with VirtualSyncModelLists using canvas drawing
- Batch status computation in _rebuild_cache() instead of per-model calls
- Reduce widget count from O(n) to O(visible_rows) for better memory usage
- Maintain synchronized scrolling between left and right model lists
- Preserve all existing functionality (search, highlighting, tooltips)

The previous implementation created individual CTkFrame widgets for each model, causing severe lag with large provider model lists. The new virtual scrolling approach draws only visible items directly on a canvas, providing smooth scrolling even with thousands of models.
…anvas coordinates

Removed manual scroll position tracking in favor of using Tkinter's built-in canvas.yview() and canvas.canvasy() methods for more reliable coordinate transformations.

- Removed `_scroll_position` instance variable that was redundantly tracking scroll state
- Updated `_get_index_at_y()` to use `canvas.canvasy()` for window-to-canvas coordinate conversion
- Modified `_render()` to retrieve scroll position from `canvas.yview()[0]` instead of cached value
- Simplified item rendering by using absolute positions in the scroll region, letting canvas handle viewport clipping
- Updated `get_scroll_position()` and `set_scroll_position()` to work directly with canvas methods
- Added explicit `_render()` call in `scroll_to_model()` to ensure UI updates after programmatic scrolling
- Fixed scroll synchronization by reconfiguring scrollbar commands after method override and consolidating render calls into `set_scroll_position()`
- Removed redundant manual `_render()` calls throughout sync handlers, as they now occur automatically

This change eliminates state synchronization issues between manual tracking and actual canvas state, making the scrolling behavior more predictable and maintainable.
…ring

Refactored the rule panel to use a high-performance virtual list implementation instead of creating individual CTkFrame widgets for each filter rule.

- Implemented `VirtualRuleList` class using raw tkinter Canvas for direct rendering
- Only renders visible rules based on scroll position, dramatically reducing memory usage
- Maintains all interactive features: hover states, tooltips, click handling, and rule highlighting
- Integrated seamless scrolling with auto-scroll to highlighted rules
- Removed `RuleChip` widget dependency from `RulePanel`, replacing with virtual list delegation
- Added model deduplication in `_on_models_loaded` to prevent duplicate entries
- Optimized tooltip management to prevent memory leaks and duplicate tooltip instances

This change significantly improves UI responsiveness when displaying large numbers of filter rules by eliminating the overhead of creating and managing hundreds of individual widget instances.
…ayout

Systematically reduced padding, margins, font sizes, and component dimensions throughout the ModelFilterGUI to create a more compact, space-efficient interface.

- Reduced title font from FONT_SIZE_NORMAL to FONT_SIZE_SMALL in RulePanel
- Decreased padding values (12→10, 8→6, etc.) across all UI components
- Reduced input entry and button heights from 36px to 28px, and button from 26px to smaller sizes
- Set minimum height constraint (70px) on rule list to prevent collapse
- Implemented grid-based responsive layout with proportional row weights (3:1 ratio for models vs rules)
- Prevented input frame height changes using pack_propagate(False)
- Refactored UI creation into _create_main_layout() with grid system replacing individual pack() calls
- Updated all components to use content_frame.grid() instead of self.pack() for better layout control

The changes maintain all functionality while significantly improving vertical space utilization, allowing more content to be visible without scrolling.
…ts and grid ratios

This commit restructures the model filter GUI layout to use a grid-based system with proper weight ratios and minimum height constraints, ensuring stable proportions during window resizing.

- Reduce minimum window dimensions from 850x600 to 600x400 for better flexibility
- Implement 3:1 grid weight ratio between model lists (weight=3) and rule panels (weight=1)
- Add grid_propagate(False) to key containers to prevent content from dictating frame sizes
- Reorganize RulePanel layout: title at top, input frame at bottom (packed first to reserve space), rule list in middle
- Set minimum row sizes: 200px for model lists, 55px for rule panels
- Remove obsolete RuleChip class (141 lines) - functionality now handled by VirtualRuleList
- Adjust padding and spacing values for more compact layout

The new grid-based approach ensures consistent proportional sizing and prevents UI elements from being squished or expanding unpredictably during window resizing.
Add complete documentation for the Model Filter GUI feature including overview, features, keyboard shortcuts, context menu operations, and proxy integration details.

- Documents GUI launch methods and provider selection
- Explains ignore/whitelist rule system with wildcard support
- Details dual-pane model view with color-coded status indicators
- Lists all keyboard shortcuts (Ctrl+S, Ctrl+R, Ctrl+F, F1, Escape)
- Describes right-click context menu functionality
- Clarifies integration flow with RotatingClient and .env persistence
- Adds cross-reference to Section 6 in project overview
@Mirrowel
Copy link
Owner Author

Mirrowel commented Dec 9, 2025

State of Python GUI libraries kinda sucks.
CustomTKinter is highly manual, CPU-bound, etc.
NiceGUI is very nice and web-based, but startup delay, having to host a local server.
DearPyGUI seems nice, it's basically ImGUI, but on python. Has same problems as imgui- not really meant to be used in full on apps and tools.

… filter rules

This commit introduces comprehensive pattern management features to the Model Filter GUI, significantly improving the user experience for managing filter rules.

Core features added:
- Smart pattern merge logic that prevents redundant rules by detecting when patterns are covered by existing broader patterns (e.g., "gpt-4" is covered by "gpt-4*")
- Pattern coverage detection system with three new methods in FilterEngine: `pattern_is_covered_by`, `is_pattern_covered`, and `get_covered_patterns`
- Import/Export functionality for filter rules with dedicated dialogs (ImportRulesDialog, ImportResultDialog)
- Copy-to-clipboard buttons for all model lists and rule panels, enabling easy pattern transfer
- Replace mode for imports that clears all existing rules vs. merge mode for incremental additions

UI improvements:
- Refactored HelpWindow to use CTkTextbox instead of CTkScrollableFrame, fixing scrolling issues with dark theme
- Proper text formatting with configurable tags for titles, sections, and content
- Enhanced rule panel headers showing rule counts and action buttons (Import/Copy)
- Model list headers with copy buttons for filtered and all models
- Improved tooltip positioning calculation for virtual rule list

The smart merge system eliminates duplicate or redundant patterns automatically:
- When adding "gpt-4*", existing "gpt-4" and "gpt-4-turbo" rules are removed as they're now covered
- When adding "gpt-4", it's skipped if "gpt-4*" already exists
- Wildcard "*" covers everything and prevents addition of any other patterns

This creates a more intuitive workflow where users can paste comma-separated model lists, import them in bulk, and the system intelligently consolidates them into minimal effective rulesets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants