pomera-ai-commander 0.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +105 -680
- package/bin/pomera-ai-commander.js +62 -62
- package/core/__init__.py +65 -65
- package/core/app_context.py +482 -482
- package/core/async_text_processor.py +421 -421
- package/core/backup_manager.py +655 -655
- package/core/backup_recovery_manager.py +1033 -1033
- package/core/content_hash_cache.py +508 -508
- package/core/context_menu.py +313 -313
- package/core/data_validator.py +1066 -1066
- package/core/database_connection_manager.py +744 -744
- package/core/database_curl_settings_manager.py +608 -608
- package/core/database_promera_ai_settings_manager.py +446 -446
- package/core/database_schema.py +411 -411
- package/core/database_schema_manager.py +395 -395
- package/core/database_settings_manager.py +1507 -1507
- package/core/database_settings_manager_interface.py +456 -456
- package/core/dialog_manager.py +734 -734
- package/core/efficient_line_numbers.py +510 -510
- package/core/error_handler.py +746 -746
- package/core/error_service.py +431 -431
- package/core/event_consolidator.py +511 -511
- package/core/mcp/__init__.py +43 -43
- package/core/mcp/protocol.py +288 -288
- package/core/mcp/schema.py +251 -251
- package/core/mcp/server_stdio.py +299 -299
- package/core/mcp/tool_registry.py +2372 -2345
- package/core/memory_efficient_text_widget.py +711 -711
- package/core/migration_manager.py +914 -914
- package/core/migration_test_suite.py +1085 -1085
- package/core/migration_validator.py +1143 -1143
- package/core/optimized_find_replace.py +714 -714
- package/core/optimized_pattern_engine.py +424 -424
- package/core/optimized_search_highlighter.py +552 -552
- package/core/performance_monitor.py +674 -674
- package/core/persistence_manager.py +712 -712
- package/core/progressive_stats_calculator.py +632 -632
- package/core/regex_pattern_cache.py +529 -529
- package/core/regex_pattern_library.py +350 -350
- package/core/search_operation_manager.py +434 -434
- package/core/settings_defaults_registry.py +1087 -1087
- package/core/settings_integrity_validator.py +1111 -1111
- package/core/settings_serializer.py +557 -557
- package/core/settings_validator.py +1823 -1823
- package/core/smart_stats_calculator.py +709 -709
- package/core/statistics_update_manager.py +619 -619
- package/core/stats_config_manager.py +858 -858
- package/core/streaming_text_handler.py +723 -723
- package/core/task_scheduler.py +596 -596
- package/core/update_pattern_library.py +168 -168
- package/core/visibility_monitor.py +596 -596
- package/core/widget_cache.py +498 -498
- package/mcp.json +51 -61
- package/package.json +61 -57
- package/pomera.py +7482 -7482
- package/pomera_mcp_server.py +183 -144
- package/requirements.txt +32 -0
- package/tools/__init__.py +4 -4
- package/tools/ai_tools.py +2891 -2891
- package/tools/ascii_art_generator.py +352 -352
- package/tools/base64_tools.py +183 -183
- package/tools/base_tool.py +511 -511
- package/tools/case_tool.py +308 -308
- package/tools/column_tools.py +395 -395
- package/tools/cron_tool.py +884 -884
- package/tools/curl_history.py +600 -600
- package/tools/curl_processor.py +1207 -1207
- package/tools/curl_settings.py +502 -502
- package/tools/curl_tool.py +5467 -5467
- package/tools/diff_viewer.py +1071 -1071
- package/tools/email_extraction_tool.py +248 -248
- package/tools/email_header_analyzer.py +425 -425
- package/tools/extraction_tools.py +250 -250
- package/tools/find_replace.py +1750 -1750
- package/tools/folder_file_reporter.py +1463 -1463
- package/tools/folder_file_reporter_adapter.py +480 -480
- package/tools/generator_tools.py +1216 -1216
- package/tools/hash_generator.py +255 -255
- package/tools/html_tool.py +656 -656
- package/tools/jsonxml_tool.py +729 -729
- package/tools/line_tools.py +419 -419
- package/tools/markdown_tools.py +561 -561
- package/tools/mcp_widget.py +1417 -1417
- package/tools/notes_widget.py +973 -973
- package/tools/number_base_converter.py +372 -372
- package/tools/regex_extractor.py +571 -571
- package/tools/slug_generator.py +310 -310
- package/tools/sorter_tools.py +458 -458
- package/tools/string_escape_tool.py +392 -392
- package/tools/text_statistics_tool.py +365 -365
- package/tools/text_wrapper.py +430 -430
- package/tools/timestamp_converter.py +421 -421
- package/tools/tool_loader.py +710 -710
- package/tools/translator_tools.py +522 -522
- package/tools/url_link_extractor.py +261 -261
- package/tools/url_parser.py +204 -204
- package/tools/whitespace_tools.py +355 -355
- package/tools/word_frequency_counter.py +146 -146
- package/core/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/__pycache__/app_context.cpython-313.pyc +0 -0
- package/core/__pycache__/async_text_processor.cpython-313.pyc +0 -0
- package/core/__pycache__/backup_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/backup_recovery_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/content_hash_cache.cpython-313.pyc +0 -0
- package/core/__pycache__/context_menu.cpython-313.pyc +0 -0
- package/core/__pycache__/data_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/database_connection_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_curl_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_promera_ai_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_schema.cpython-313.pyc +0 -0
- package/core/__pycache__/database_schema_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_settings_manager_interface.cpython-313.pyc +0 -0
- package/core/__pycache__/dialog_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/efficient_line_numbers.cpython-313.pyc +0 -0
- package/core/__pycache__/error_handler.cpython-313.pyc +0 -0
- package/core/__pycache__/error_service.cpython-313.pyc +0 -0
- package/core/__pycache__/event_consolidator.cpython-313.pyc +0 -0
- package/core/__pycache__/memory_efficient_text_widget.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_test_suite.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_find_replace.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_pattern_engine.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_search_highlighter.cpython-313.pyc +0 -0
- package/core/__pycache__/performance_monitor.cpython-313.pyc +0 -0
- package/core/__pycache__/persistence_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/progressive_stats_calculator.cpython-313.pyc +0 -0
- package/core/__pycache__/regex_pattern_cache.cpython-313.pyc +0 -0
- package/core/__pycache__/regex_pattern_library.cpython-313.pyc +0 -0
- package/core/__pycache__/search_operation_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_defaults_registry.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_integrity_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_serializer.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/smart_stats_calculator.cpython-313.pyc +0 -0
- package/core/__pycache__/statistics_update_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/stats_config_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/streaming_text_handler.cpython-313.pyc +0 -0
- package/core/__pycache__/task_scheduler.cpython-313.pyc +0 -0
- package/core/__pycache__/visibility_monitor.cpython-313.pyc +0 -0
- package/core/__pycache__/widget_cache.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/protocol.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/server_stdio.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/tool_registry.cpython-313.pyc +0 -0
- package/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/tools/__pycache__/ai_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/ascii_art_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/base64_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/base_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/case_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/column_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/cron_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_history.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_processor.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_settings.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/diff_viewer.cpython-313.pyc +0 -0
- package/tools/__pycache__/email_extraction_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/email_header_analyzer.cpython-313.pyc +0 -0
- package/tools/__pycache__/extraction_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/find_replace.cpython-313.pyc +0 -0
- package/tools/__pycache__/folder_file_reporter.cpython-313.pyc +0 -0
- package/tools/__pycache__/folder_file_reporter_adapter.cpython-313.pyc +0 -0
- package/tools/__pycache__/generator_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/hash_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/html_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/huggingface_helper.cpython-313.pyc +0 -0
- package/tools/__pycache__/jsonxml_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/line_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/list_comparator.cpython-313.pyc +0 -0
- package/tools/__pycache__/markdown_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/mcp_widget.cpython-313.pyc +0 -0
- package/tools/__pycache__/notes_widget.cpython-313.pyc +0 -0
- package/tools/__pycache__/number_base_converter.cpython-313.pyc +0 -0
- package/tools/__pycache__/regex_extractor.cpython-313.pyc +0 -0
- package/tools/__pycache__/slug_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/sorter_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/string_escape_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/text_statistics_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/text_wrapper.cpython-313.pyc +0 -0
- package/tools/__pycache__/timestamp_converter.cpython-313.pyc +0 -0
- package/tools/__pycache__/tool_loader.cpython-313.pyc +0 -0
- package/tools/__pycache__/translator_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/url_link_extractor.cpython-313.pyc +0 -0
- package/tools/__pycache__/url_parser.cpython-313.pyc +0 -0
- package/tools/__pycache__/whitespace_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/word_frequency_counter.cpython-313.pyc +0 -0
|
@@ -1,1087 +1,1087 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Settings Defaults Registry Module
|
|
3
|
-
|
|
4
|
-
Centralizes all tool default settings into a single registry system for consistent
|
|
5
|
-
first-launch initialization. Provides schema validation, deep merge capability,
|
|
6
|
-
and backward compatibility with existing tools.
|
|
7
|
-
|
|
8
|
-
Author: Pomera AI Commander Team
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from dataclasses import dataclass, field
|
|
12
|
-
from typing import Any, Dict, List, Optional, Callable, Set, Tuple
|
|
13
|
-
from copy import deepcopy
|
|
14
|
-
import logging
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class ToolDefaultsSpec:
|
|
19
|
-
"""
|
|
20
|
-
Specification for a tool's default settings.
|
|
21
|
-
|
|
22
|
-
Attributes:
|
|
23
|
-
tool_name: Unique identifier for the tool (must match key in tool_settings)
|
|
24
|
-
defaults: Dictionary of default settings for the tool
|
|
25
|
-
required_keys: Set of keys that must be present in settings
|
|
26
|
-
description: Human-readable description of the tool
|
|
27
|
-
version: Version of the settings schema (for future migrations)
|
|
28
|
-
"""
|
|
29
|
-
tool_name: str
|
|
30
|
-
defaults: Dict[str, Any]
|
|
31
|
-
required_keys: Set[str] = field(default_factory=set)
|
|
32
|
-
description: str = ""
|
|
33
|
-
version: str = "1.0"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class SettingsValidationError(Exception):
|
|
37
|
-
"""Raised when settings validation fails."""
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class SettingsDefaultsRegistry:
|
|
42
|
-
"""
|
|
43
|
-
Central registry for all tool default settings.
|
|
44
|
-
|
|
45
|
-
This registry provides:
|
|
46
|
-
- Centralized storage of all tool defaults
|
|
47
|
-
- Schema validation for tool settings
|
|
48
|
-
- Deep merge capability for user settings with defaults
|
|
49
|
-
- Backward compatibility with existing tools
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
_instance: Optional['SettingsDefaultsRegistry'] = None
|
|
53
|
-
|
|
54
|
-
def __new__(cls) -> 'SettingsDefaultsRegistry':
|
|
55
|
-
"""Singleton pattern to ensure only one registry exists."""
|
|
56
|
-
if cls._instance is None:
|
|
57
|
-
cls._instance = super().__new__(cls)
|
|
58
|
-
cls._instance._initialized = False
|
|
59
|
-
return cls._instance
|
|
60
|
-
|
|
61
|
-
def __init__(self):
|
|
62
|
-
"""Initialize the registry with default tool specifications."""
|
|
63
|
-
if self._initialized:
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
self.logger = logging.getLogger(__name__)
|
|
67
|
-
self._tool_specs: Dict[str, ToolDefaultsSpec] = {}
|
|
68
|
-
self._app_defaults: Dict[str, Any] = {}
|
|
69
|
-
self._initialized = True
|
|
70
|
-
|
|
71
|
-
# Register all built-in tool defaults
|
|
72
|
-
self._register_builtin_defaults()
|
|
73
|
-
|
|
74
|
-
def _register_builtin_defaults(self) -> None:
|
|
75
|
-
"""Register all built-in tool default settings."""
|
|
76
|
-
|
|
77
|
-
# Case Tool - Updated with new exclusions per requirements
|
|
78
|
-
self.register_tool(ToolDefaultsSpec(
|
|
79
|
-
tool_name="Case Tool",
|
|
80
|
-
defaults={
|
|
81
|
-
"mode": "Sentence",
|
|
82
|
-
"exclusions": "a\nan\nthe\nand\nbut\nor\nfor\nnor\non\nat\nto\nfrom\nby\nwith\nin\nof"
|
|
83
|
-
},
|
|
84
|
-
required_keys={"mode"},
|
|
85
|
-
description="Text case conversion tool"
|
|
86
|
-
))
|
|
87
|
-
|
|
88
|
-
# Base64 Encoder/Decoder
|
|
89
|
-
self.register_tool(ToolDefaultsSpec(
|
|
90
|
-
tool_name="Base64 Encoder/Decoder",
|
|
91
|
-
defaults={"mode": "encode"},
|
|
92
|
-
required_keys={"mode"},
|
|
93
|
-
description="Base64 encoding and decoding tool"
|
|
94
|
-
))
|
|
95
|
-
|
|
96
|
-
# JSON/XML Tool
|
|
97
|
-
self.register_tool(ToolDefaultsSpec(
|
|
98
|
-
tool_name="JSON/XML Tool",
|
|
99
|
-
defaults={
|
|
100
|
-
"operation": "json_to_xml",
|
|
101
|
-
"json_indent": 2,
|
|
102
|
-
"xml_indent": 2,
|
|
103
|
-
"preserve_attributes": True,
|
|
104
|
-
"sort_keys": False,
|
|
105
|
-
"array_wrapper": "item",
|
|
106
|
-
"root_element": "root",
|
|
107
|
-
"jsonpath_query": "$",
|
|
108
|
-
"xpath_query": "//*"
|
|
109
|
-
},
|
|
110
|
-
required_keys={"operation"},
|
|
111
|
-
description="JSON and XML conversion tool"
|
|
112
|
-
))
|
|
113
|
-
|
|
114
|
-
# Cron Tool
|
|
115
|
-
self.register_tool(ToolDefaultsSpec(
|
|
116
|
-
tool_name="Cron Tool",
|
|
117
|
-
defaults={
|
|
118
|
-
"action": "parse_explain",
|
|
119
|
-
"preset_category": "Daily Schedules",
|
|
120
|
-
"preset_pattern": "Daily at midnight",
|
|
121
|
-
"compare_expressions": "",
|
|
122
|
-
"next_runs_count": 10
|
|
123
|
-
},
|
|
124
|
-
required_keys={"action"},
|
|
125
|
-
description="Cron expression parser and generator"
|
|
126
|
-
))
|
|
127
|
-
|
|
128
|
-
# Find & Replace Text
|
|
129
|
-
self.register_tool(ToolDefaultsSpec(
|
|
130
|
-
tool_name="Find & Replace Text",
|
|
131
|
-
defaults={
|
|
132
|
-
"find": "",
|
|
133
|
-
"replace": "",
|
|
134
|
-
"mode": "Text",
|
|
135
|
-
"option": "ignore_case",
|
|
136
|
-
"find_history": [],
|
|
137
|
-
"replace_history": []
|
|
138
|
-
},
|
|
139
|
-
required_keys={"mode"},
|
|
140
|
-
description="Find and replace text tool"
|
|
141
|
-
))
|
|
142
|
-
|
|
143
|
-
# Generator Tools
|
|
144
|
-
self.register_tool(ToolDefaultsSpec(
|
|
145
|
-
tool_name="Generator Tools",
|
|
146
|
-
defaults={
|
|
147
|
-
"Strong Password Generator": {
|
|
148
|
-
"length": 20,
|
|
149
|
-
"numbers": "",
|
|
150
|
-
"symbols": ""
|
|
151
|
-
},
|
|
152
|
-
"Repeating Text Generator": {
|
|
153
|
-
"times": 5,
|
|
154
|
-
"separator": "+"
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
description="Various text and data generators"
|
|
158
|
-
))
|
|
159
|
-
|
|
160
|
-
# Sorter Tools
|
|
161
|
-
self.register_tool(ToolDefaultsSpec(
|
|
162
|
-
tool_name="Sorter Tools",
|
|
163
|
-
defaults={
|
|
164
|
-
"Number Sorter": {
|
|
165
|
-
"order": "ascending"
|
|
166
|
-
},
|
|
167
|
-
"Alphabetical Sorter": {
|
|
168
|
-
"order": "ascending",
|
|
169
|
-
"unique_only": False,
|
|
170
|
-
"trim": False
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
description="Text and number sorting tools"
|
|
174
|
-
))
|
|
175
|
-
|
|
176
|
-
# URL and Link Extractor
|
|
177
|
-
self.register_tool(ToolDefaultsSpec(
|
|
178
|
-
tool_name="URL and Link Extractor",
|
|
179
|
-
defaults={
|
|
180
|
-
"extract_href": False,
|
|
181
|
-
"extract_https": False,
|
|
182
|
-
"extract_any_protocol": False,
|
|
183
|
-
"extract_markdown": False,
|
|
184
|
-
"filter_text": ""
|
|
185
|
-
},
|
|
186
|
-
description="URL and link extraction tool"
|
|
187
|
-
))
|
|
188
|
-
|
|
189
|
-
# Email Extraction Tool
|
|
190
|
-
self.register_tool(ToolDefaultsSpec(
|
|
191
|
-
tool_name="Email Extraction Tool",
|
|
192
|
-
defaults={
|
|
193
|
-
"omit_duplicates": False,
|
|
194
|
-
"hide_counts": True,
|
|
195
|
-
"sort_emails": False,
|
|
196
|
-
"only_domain": False
|
|
197
|
-
},
|
|
198
|
-
description="Email address extraction tool"
|
|
199
|
-
))
|
|
200
|
-
|
|
201
|
-
# Regex Extractor
|
|
202
|
-
self.register_tool(ToolDefaultsSpec(
|
|
203
|
-
tool_name="Regex Extractor",
|
|
204
|
-
defaults={
|
|
205
|
-
"pattern": "",
|
|
206
|
-
"match_mode": "all_per_line",
|
|
207
|
-
"omit_duplicates": False,
|
|
208
|
-
"hide_counts": True,
|
|
209
|
-
"sort_results": False,
|
|
210
|
-
"case_sensitive": False
|
|
211
|
-
},
|
|
212
|
-
required_keys={"match_mode"},
|
|
213
|
-
description="Regular expression extraction tool"
|
|
214
|
-
))
|
|
215
|
-
|
|
216
|
-
# Email Header Analyzer
|
|
217
|
-
self.register_tool(ToolDefaultsSpec(
|
|
218
|
-
tool_name="Email Header Analyzer",
|
|
219
|
-
defaults={
|
|
220
|
-
"show_timestamps": True,
|
|
221
|
-
"show_delays": True,
|
|
222
|
-
"show_authentication": True,
|
|
223
|
-
"show_spam_score": True
|
|
224
|
-
},
|
|
225
|
-
description="Email header analysis tool"
|
|
226
|
-
))
|
|
227
|
-
|
|
228
|
-
# Folder File Reporter
|
|
229
|
-
self.register_tool(ToolDefaultsSpec(
|
|
230
|
-
tool_name="Folder File Reporter",
|
|
231
|
-
defaults={
|
|
232
|
-
"last_input_folder": "",
|
|
233
|
-
"last_output_folder": "",
|
|
234
|
-
"field_selections": {
|
|
235
|
-
"path": True,
|
|
236
|
-
"name": True,
|
|
237
|
-
"size": True,
|
|
238
|
-
"date_modified": True
|
|
239
|
-
},
|
|
240
|
-
"separator": " | ",
|
|
241
|
-
"folders_only": False,
|
|
242
|
-
"recursion_mode": "full",
|
|
243
|
-
"recursion_depth": 2,
|
|
244
|
-
"size_format": "human",
|
|
245
|
-
"date_format": "%Y-%m-%d %H:%M:%S"
|
|
246
|
-
},
|
|
247
|
-
description="Folder and file reporting tool"
|
|
248
|
-
))
|
|
249
|
-
|
|
250
|
-
# URL Parser
|
|
251
|
-
self.register_tool(ToolDefaultsSpec(
|
|
252
|
-
tool_name="URL Parser",
|
|
253
|
-
defaults={"ascii_decode": True},
|
|
254
|
-
description="URL parsing and analysis tool"
|
|
255
|
-
))
|
|
256
|
-
|
|
257
|
-
# Word Frequency Counter
|
|
258
|
-
self.register_tool(ToolDefaultsSpec(
|
|
259
|
-
tool_name="Word Frequency Counter",
|
|
260
|
-
defaults={},
|
|
261
|
-
description="Word frequency analysis tool"
|
|
262
|
-
))
|
|
263
|
-
|
|
264
|
-
# Google AI - Updated December 2025
|
|
265
|
-
# Latest: Gemini 2.5 series (Pro, Flash, Flash-Lite), Gemini 2.0 series
|
|
266
|
-
self.register_tool(ToolDefaultsSpec(
|
|
267
|
-
tool_name="Google AI",
|
|
268
|
-
defaults={
|
|
269
|
-
"API_KEY": "putinyourkey",
|
|
270
|
-
"MODEL": "gemini-2.5-pro",
|
|
271
|
-
"MODELS_LIST": [
|
|
272
|
-
"gemini-2.5-pro",
|
|
273
|
-
"gemini-2.5-flash",
|
|
274
|
-
"gemini-2.5-flash-lite",
|
|
275
|
-
"gemini-2.0-flash",
|
|
276
|
-
"gemini-2.0-flash-lite",
|
|
277
|
-
"gemini-1.5-pro-latest",
|
|
278
|
-
"gemini-1.5-flash-latest"
|
|
279
|
-
],
|
|
280
|
-
"system_prompt": "You are a helpful assistant.",
|
|
281
|
-
"temperature": 0.7,
|
|
282
|
-
"topK": 40,
|
|
283
|
-
"topP": 0.95,
|
|
284
|
-
"candidateCount": 1,
|
|
285
|
-
"maxOutputTokens": 8192,
|
|
286
|
-
"stopSequences": ""
|
|
287
|
-
},
|
|
288
|
-
required_keys={"API_KEY", "MODEL"},
|
|
289
|
-
description="Google AI (Gemini) integration"
|
|
290
|
-
))
|
|
291
|
-
|
|
292
|
-
# Azure AI - Updated December 2025
|
|
293
|
-
# Latest: GPT-4.1 series (4.1, 4.1-mini, 4.1-nano), GPT-4o being retired Feb 2026
|
|
294
|
-
self.register_tool(ToolDefaultsSpec(
|
|
295
|
-
tool_name="Azure AI",
|
|
296
|
-
defaults={
|
|
297
|
-
"API_KEY": "putinyourkey",
|
|
298
|
-
"MODEL": "gpt-4.1",
|
|
299
|
-
"MODELS_LIST": [
|
|
300
|
-
"gpt-4.1",
|
|
301
|
-
"gpt-4.1-mini",
|
|
302
|
-
"gpt-4.1-nano",
|
|
303
|
-
"gpt-4o",
|
|
304
|
-
"gpt-4o-mini",
|
|
305
|
-
"gpt-4-turbo"
|
|
306
|
-
],
|
|
307
|
-
"ENDPOINT": "",
|
|
308
|
-
"API_VERSION": "2024-10-21",
|
|
309
|
-
"system_prompt": "You are a helpful assistant.",
|
|
310
|
-
"temperature": 0.7,
|
|
311
|
-
"max_tokens": 4096,
|
|
312
|
-
"top_p": 1.0,
|
|
313
|
-
"frequency_penalty": 0.0,
|
|
314
|
-
"presence_penalty": 0.0,
|
|
315
|
-
"seed": "",
|
|
316
|
-
"stop": ""
|
|
317
|
-
},
|
|
318
|
-
required_keys={"API_KEY", "MODEL", "ENDPOINT"},
|
|
319
|
-
description="Azure OpenAI integration"
|
|
320
|
-
))
|
|
321
|
-
|
|
322
|
-
# Anthropic AI - Updated December 2025
|
|
323
|
-
# Latest: Claude 4 series (Opus 4.5, Sonnet 4.5, Sonnet 4, Opus 4)
|
|
324
|
-
self.register_tool(ToolDefaultsSpec(
|
|
325
|
-
tool_name="Anthropic AI",
|
|
326
|
-
defaults={
|
|
327
|
-
"API_KEY": "putinyourkey",
|
|
328
|
-
"MODEL": "claude-sonnet-4-5-20250929",
|
|
329
|
-
"MODELS_LIST": [
|
|
330
|
-
"claude-sonnet-4-5-20250929",
|
|
331
|
-
"claude-opus-4-5-20251124",
|
|
332
|
-
"claude-sonnet-4-20250522",
|
|
333
|
-
"claude-opus-4-20250522",
|
|
334
|
-
"claude-3-5-sonnet-20241022",
|
|
335
|
-
"claude-3-5-haiku-20241022",
|
|
336
|
-
"claude-3-opus-20240229"
|
|
337
|
-
],
|
|
338
|
-
"system": "You are a helpful assistant.",
|
|
339
|
-
"max_tokens": 4096,
|
|
340
|
-
"temperature": 0.7,
|
|
341
|
-
"top_p": 0.9,
|
|
342
|
-
"top_k": 40,
|
|
343
|
-
"stop_sequences": ""
|
|
344
|
-
},
|
|
345
|
-
required_keys={"API_KEY", "MODEL"},
|
|
346
|
-
description="Anthropic Claude AI integration"
|
|
347
|
-
))
|
|
348
|
-
|
|
349
|
-
# OpenAI - Updated December 2025
|
|
350
|
-
# Latest: GPT-4.1 series, GPT-4o being retired Feb 2026
|
|
351
|
-
self.register_tool(ToolDefaultsSpec(
|
|
352
|
-
tool_name="OpenAI",
|
|
353
|
-
defaults={
|
|
354
|
-
"API_KEY": "putinyourkey",
|
|
355
|
-
"MODEL": "gpt-4.1",
|
|
356
|
-
"MODELS_LIST": [
|
|
357
|
-
"gpt-4.1",
|
|
358
|
-
"gpt-4.1-mini",
|
|
359
|
-
"gpt-4.1-nano",
|
|
360
|
-
"gpt-4o",
|
|
361
|
-
"gpt-4o-mini",
|
|
362
|
-
"gpt-4-turbo",
|
|
363
|
-
"o1-preview",
|
|
364
|
-
"o1-mini"
|
|
365
|
-
],
|
|
366
|
-
"system_prompt": "You are a helpful assistant.",
|
|
367
|
-
"temperature": 0.7,
|
|
368
|
-
"max_tokens": 4096,
|
|
369
|
-
"top_p": 1.0,
|
|
370
|
-
"frequency_penalty": 0.0,
|
|
371
|
-
"presence_penalty": 0.0,
|
|
372
|
-
"seed": "",
|
|
373
|
-
"response_format": "text",
|
|
374
|
-
"stop": ""
|
|
375
|
-
},
|
|
376
|
-
required_keys={"API_KEY", "MODEL"},
|
|
377
|
-
description="OpenAI GPT integration"
|
|
378
|
-
))
|
|
379
|
-
|
|
380
|
-
# Cohere AI - Updated December 2025
|
|
381
|
-
# Latest: Command A (March 2025), Command R+ (08-2024), Command R (08-2024)
|
|
382
|
-
self.register_tool(ToolDefaultsSpec(
|
|
383
|
-
tool_name="Cohere AI",
|
|
384
|
-
defaults={
|
|
385
|
-
"API_KEY": "putinyourkey",
|
|
386
|
-
"MODEL": "command-a-03-2025",
|
|
387
|
-
"MODELS_LIST": [
|
|
388
|
-
"command-a-03-2025",
|
|
389
|
-
"command-r-plus-08-2024",
|
|
390
|
-
"command-r-08-2024",
|
|
391
|
-
"command-r-plus",
|
|
392
|
-
"command-r",
|
|
393
|
-
"command-light"
|
|
394
|
-
],
|
|
395
|
-
"preamble": "You are a helpful assistant.",
|
|
396
|
-
"temperature": 0.7,
|
|
397
|
-
"max_tokens": 4000,
|
|
398
|
-
"k": 50,
|
|
399
|
-
"p": 0.75,
|
|
400
|
-
"frequency_penalty": 0.0,
|
|
401
|
-
"presence_penalty": 0.0,
|
|
402
|
-
"stop_sequences": "",
|
|
403
|
-
"citation_quality": "accurate"
|
|
404
|
-
},
|
|
405
|
-
required_keys={"API_KEY", "MODEL"},
|
|
406
|
-
description="Cohere AI integration"
|
|
407
|
-
))
|
|
408
|
-
|
|
409
|
-
# HuggingFace AI - Updated December 2025
|
|
410
|
-
# Latest: Llama 3.3, Mistral Small 3, Qwen 2.5
|
|
411
|
-
self.register_tool(ToolDefaultsSpec(
|
|
412
|
-
tool_name="HuggingFace AI",
|
|
413
|
-
defaults={
|
|
414
|
-
"API_KEY": "putinyourkey",
|
|
415
|
-
"MODEL": "meta-llama/Llama-3.3-70B-Instruct",
|
|
416
|
-
"MODELS_LIST": [
|
|
417
|
-
"meta-llama/Llama-3.3-70B-Instruct",
|
|
418
|
-
"meta-llama/Meta-Llama-3.1-70B-Instruct",
|
|
419
|
-
"meta-llama/Meta-Llama-3.1-8B-Instruct",
|
|
420
|
-
"mistralai/Mistral-Small-3-Instruct",
|
|
421
|
-
"mistralai/Mistral-7B-Instruct-v0.3",
|
|
422
|
-
"Qwen/Qwen2.5-72B-Instruct",
|
|
423
|
-
"google/gemma-2-27b-it"
|
|
424
|
-
],
|
|
425
|
-
"system_prompt": "You are a helpful assistant.",
|
|
426
|
-
"max_tokens": 4096,
|
|
427
|
-
"temperature": 0.7,
|
|
428
|
-
"top_p": 0.95,
|
|
429
|
-
"stop_sequences": "",
|
|
430
|
-
"seed": ""
|
|
431
|
-
},
|
|
432
|
-
required_keys={"API_KEY", "MODEL"},
|
|
433
|
-
description="HuggingFace AI integration"
|
|
434
|
-
))
|
|
435
|
-
|
|
436
|
-
# Groq AI - Updated December 2025
|
|
437
|
-
# Latest: Llama 3.3 70B, Mixtral 8x7B, Gemma 2
|
|
438
|
-
self.register_tool(ToolDefaultsSpec(
|
|
439
|
-
tool_name="Groq AI",
|
|
440
|
-
defaults={
|
|
441
|
-
"API_KEY": "putinyourkey",
|
|
442
|
-
"MODEL": "llama-3.3-70b-versatile",
|
|
443
|
-
"MODELS_LIST": [
|
|
444
|
-
"llama-3.3-70b-versatile",
|
|
445
|
-
"llama-3.1-70b-versatile",
|
|
446
|
-
"llama-3.1-8b-instant",
|
|
447
|
-
"mixtral-8x7b-32768",
|
|
448
|
-
"gemma2-9b-it",
|
|
449
|
-
"llama-guard-3-8b"
|
|
450
|
-
],
|
|
451
|
-
"system_prompt": "You are a helpful assistant.",
|
|
452
|
-
"temperature": 0.7,
|
|
453
|
-
"max_tokens": 8192,
|
|
454
|
-
"top_p": 1.0,
|
|
455
|
-
"frequency_penalty": 0.0,
|
|
456
|
-
"presence_penalty": 0.0,
|
|
457
|
-
"stop": "",
|
|
458
|
-
"seed": "",
|
|
459
|
-
"response_format": "text"
|
|
460
|
-
},
|
|
461
|
-
required_keys={"API_KEY", "MODEL"},
|
|
462
|
-
description="Groq AI integration"
|
|
463
|
-
))
|
|
464
|
-
|
|
465
|
-
# OpenRouterAI - Updated December 2025
|
|
466
|
-
# Latest: Claude Opus 4.5, GPT-4.1, Gemini 2.5, DeepSeek 3.2
|
|
467
|
-
self.register_tool(ToolDefaultsSpec(
|
|
468
|
-
tool_name="OpenRouterAI",
|
|
469
|
-
defaults={
|
|
470
|
-
"API_KEY": "putinyourkey",
|
|
471
|
-
"MODEL": "anthropic/claude-sonnet-4.5",
|
|
472
|
-
"MODELS_LIST": [
|
|
473
|
-
"anthropic/claude-sonnet-4.5",
|
|
474
|
-
"anthropic/claude-opus-4.5",
|
|
475
|
-
"openai/gpt-4.1",
|
|
476
|
-
"google/gemini-2.5-pro",
|
|
477
|
-
"google/gemini-2.5-flash",
|
|
478
|
-
"deepseek/deepseek-chat",
|
|
479
|
-
"meta-llama/llama-3.3-70b-instruct",
|
|
480
|
-
"google/gemini-2.0-flash:free",
|
|
481
|
-
"meta-llama/llama-3.1-8b-instruct:free"
|
|
482
|
-
],
|
|
483
|
-
"system_prompt": "You are a helpful assistant.",
|
|
484
|
-
"temperature": 0.7,
|
|
485
|
-
"max_tokens": 4096,
|
|
486
|
-
"top_p": 1.0,
|
|
487
|
-
"top_k": 0,
|
|
488
|
-
"frequency_penalty": 0.0,
|
|
489
|
-
"presence_penalty": 0.0,
|
|
490
|
-
"repetition_penalty": 1.0,
|
|
491
|
-
"seed": "",
|
|
492
|
-
"stop": ""
|
|
493
|
-
},
|
|
494
|
-
required_keys={"API_KEY", "MODEL"},
|
|
495
|
-
description="OpenRouter AI integration"
|
|
496
|
-
))
|
|
497
|
-
|
|
498
|
-
# AWS Bedrock - Updated December 2025
|
|
499
|
-
# Latest: Claude 3.5 Sonnet v2, Claude 3.5 Haiku, Llama 3.2, Titan G1
|
|
500
|
-
self.register_tool(ToolDefaultsSpec(
|
|
501
|
-
tool_name="AWS Bedrock",
|
|
502
|
-
defaults={
|
|
503
|
-
"ACCESS_KEY": "",
|
|
504
|
-
"SECRET_KEY": "",
|
|
505
|
-
"REGION": "us-east-1",
|
|
506
|
-
"MODEL": "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
507
|
-
"MODELS_LIST": [
|
|
508
|
-
"anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
509
|
-
"anthropic.claude-3-5-haiku-20241022-v1:0",
|
|
510
|
-
"anthropic.claude-3-opus-20240229-v1:0",
|
|
511
|
-
"anthropic.claude-3-sonnet-20240229-v1:0",
|
|
512
|
-
"meta.llama3-2-90b-instruct-v1:0",
|
|
513
|
-
"meta.llama3-2-11b-instruct-v1:0",
|
|
514
|
-
"meta.llama3-1-70b-instruct-v1:0",
|
|
515
|
-
"meta.llama3-1-8b-instruct-v1:0",
|
|
516
|
-
"amazon.titan-text-premier-v1:0",
|
|
517
|
-
"amazon.titan-text-express-v1",
|
|
518
|
-
"mistral.mixtral-8x7b-instruct-v0:1"
|
|
519
|
-
],
|
|
520
|
-
"system_prompt": "You are a helpful assistant.",
|
|
521
|
-
"temperature": 0.7,
|
|
522
|
-
"max_tokens": 4096,
|
|
523
|
-
"top_p": 0.9,
|
|
524
|
-
"top_k": 40
|
|
525
|
-
},
|
|
526
|
-
required_keys={"ACCESS_KEY", "SECRET_KEY", "REGION", "MODEL"},
|
|
527
|
-
description="AWS Bedrock AI integration"
|
|
528
|
-
))
|
|
529
|
-
|
|
530
|
-
# Vertex AI - Updated December 2025
|
|
531
|
-
# Latest: Gemini 2.5 series (Pro, Flash, Flash-Lite)
|
|
532
|
-
self.register_tool(ToolDefaultsSpec(
|
|
533
|
-
tool_name="Vertex AI",
|
|
534
|
-
defaults={
|
|
535
|
-
"PROJECT_ID": "",
|
|
536
|
-
"LOCATION": "us-central1",
|
|
537
|
-
"MODEL": "gemini-2.5-pro",
|
|
538
|
-
"MODELS_LIST": [
|
|
539
|
-
"gemini-2.5-pro",
|
|
540
|
-
"gemini-2.5-flash",
|
|
541
|
-
"gemini-2.5-flash-lite",
|
|
542
|
-
"gemini-2.0-flash",
|
|
543
|
-
"gemini-2.0-flash-lite",
|
|
544
|
-
"gemini-1.5-pro",
|
|
545
|
-
"gemini-1.5-flash"
|
|
546
|
-
],
|
|
547
|
-
"system_prompt": "You are a helpful assistant.",
|
|
548
|
-
"temperature": 0.7,
|
|
549
|
-
"max_tokens": 8192,
|
|
550
|
-
"top_p": 0.95,
|
|
551
|
-
"top_k": 40
|
|
552
|
-
},
|
|
553
|
-
required_keys={"PROJECT_ID", "LOCATION", "MODEL"},
|
|
554
|
-
description="Google Vertex AI integration"
|
|
555
|
-
))
|
|
556
|
-
|
|
557
|
-
# AI Tools (managed by AIToolsWidget)
|
|
558
|
-
self.register_tool(ToolDefaultsSpec(
|
|
559
|
-
tool_name="AI Tools",
|
|
560
|
-
defaults={},
|
|
561
|
-
description="AI Tools settings managed by AIToolsWidget"
|
|
562
|
-
))
|
|
563
|
-
|
|
564
|
-
# Diff Viewer
|
|
565
|
-
self.register_tool(ToolDefaultsSpec(
|
|
566
|
-
tool_name="Diff Viewer",
|
|
567
|
-
defaults={"option": "ignore_case"},
|
|
568
|
-
description="Text diff comparison tool"
|
|
569
|
-
))
|
|
570
|
-
|
|
571
|
-
# List Comparator
|
|
572
|
-
self.register_tool(ToolDefaultsSpec(
|
|
573
|
-
tool_name="List Comparator",
|
|
574
|
-
defaults={
|
|
575
|
-
"operation": "unique_to_first",
|
|
576
|
-
"case_sensitive": False,
|
|
577
|
-
"trim_whitespace": True
|
|
578
|
-
},
|
|
579
|
-
description="List comparison tool"
|
|
580
|
-
))
|
|
581
|
-
|
|
582
|
-
# HTML Tool
|
|
583
|
-
self.register_tool(ToolDefaultsSpec(
|
|
584
|
-
tool_name="HTML Tool",
|
|
585
|
-
defaults={
|
|
586
|
-
"operation": "strip_tags",
|
|
587
|
-
"preserve_links": False,
|
|
588
|
-
"preserve_images": False
|
|
589
|
-
},
|
|
590
|
-
description="HTML processing tool"
|
|
591
|
-
))
|
|
592
|
-
|
|
593
|
-
# Line Tools
|
|
594
|
-
self.register_tool(ToolDefaultsSpec(
|
|
595
|
-
tool_name="Line Tools",
|
|
596
|
-
defaults={
|
|
597
|
-
"duplicate_mode": "keep_first",
|
|
598
|
-
"case_sensitive": True,
|
|
599
|
-
"preserve_single": False,
|
|
600
|
-
"number_format": "1. ",
|
|
601
|
-
"start_number": 1,
|
|
602
|
-
"skip_empty": False
|
|
603
|
-
},
|
|
604
|
-
required_keys={"duplicate_mode"},
|
|
605
|
-
description="Line manipulation utilities"
|
|
606
|
-
))
|
|
607
|
-
|
|
608
|
-
# Whitespace Tools
|
|
609
|
-
self.register_tool(ToolDefaultsSpec(
|
|
610
|
-
tool_name="Whitespace Tools",
|
|
611
|
-
defaults={
|
|
612
|
-
"trim_mode": "both",
|
|
613
|
-
"preserve_indent": False,
|
|
614
|
-
"tab_size": 4,
|
|
615
|
-
"line_ending": "lf"
|
|
616
|
-
},
|
|
617
|
-
description="Whitespace manipulation utilities"
|
|
618
|
-
))
|
|
619
|
-
|
|
620
|
-
# Text Statistics
|
|
621
|
-
self.register_tool(ToolDefaultsSpec(
|
|
622
|
-
tool_name="Text Statistics",
|
|
623
|
-
defaults={
|
|
624
|
-
"words_per_minute": 200,
|
|
625
|
-
"show_frequency": True,
|
|
626
|
-
"frequency_count": 10
|
|
627
|
-
},
|
|
628
|
-
description="Comprehensive text analysis tool"
|
|
629
|
-
))
|
|
630
|
-
|
|
631
|
-
# Hash Generator
|
|
632
|
-
self.register_tool(ToolDefaultsSpec(
|
|
633
|
-
tool_name="Hash Generator",
|
|
634
|
-
defaults={
|
|
635
|
-
"algorithms": ["md5", "sha256"],
|
|
636
|
-
"uppercase": False
|
|
637
|
-
},
|
|
638
|
-
description="Cryptographic hash generation tool"
|
|
639
|
-
))
|
|
640
|
-
|
|
641
|
-
# Markdown Tools
|
|
642
|
-
self.register_tool(ToolDefaultsSpec(
|
|
643
|
-
tool_name="Markdown Tools",
|
|
644
|
-
defaults={
|
|
645
|
-
"preserve_links_text": True,
|
|
646
|
-
"include_images": False,
|
|
647
|
-
"header_format": "indented",
|
|
648
|
-
"csv_delimiter": ","
|
|
649
|
-
},
|
|
650
|
-
description="Markdown processing utilities"
|
|
651
|
-
))
|
|
652
|
-
|
|
653
|
-
# String Escape Tool
|
|
654
|
-
self.register_tool(ToolDefaultsSpec(
|
|
655
|
-
tool_name="String Escape Tool",
|
|
656
|
-
defaults={
|
|
657
|
-
"format": "json",
|
|
658
|
-
"mode": "escape",
|
|
659
|
-
"plus_spaces": False
|
|
660
|
-
},
|
|
661
|
-
description="String escape/unescape utilities"
|
|
662
|
-
))
|
|
663
|
-
|
|
664
|
-
# Number Base Converter
|
|
665
|
-
self.register_tool(ToolDefaultsSpec(
|
|
666
|
-
tool_name="Number Base Converter",
|
|
667
|
-
defaults={
|
|
668
|
-
"input_base": "decimal",
|
|
669
|
-
"output_base": "hex",
|
|
670
|
-
"uppercase": True,
|
|
671
|
-
"show_prefix": True
|
|
672
|
-
},
|
|
673
|
-
description="Number base conversion tool"
|
|
674
|
-
))
|
|
675
|
-
|
|
676
|
-
# Text Wrapper
|
|
677
|
-
self.register_tool(ToolDefaultsSpec(
|
|
678
|
-
tool_name="Text Wrapper",
|
|
679
|
-
defaults={
|
|
680
|
-
"wrap_width": 80,
|
|
681
|
-
"justify_mode": "left",
|
|
682
|
-
"justify_width": 80,
|
|
683
|
-
"prefix": "",
|
|
684
|
-
"suffix": "",
|
|
685
|
-
"skip_empty": True,
|
|
686
|
-
"indent_size": 4,
|
|
687
|
-
"indent_char": "space",
|
|
688
|
-
"quote_style": "double"
|
|
689
|
-
},
|
|
690
|
-
description="Text wrapping and formatting tool"
|
|
691
|
-
))
|
|
692
|
-
|
|
693
|
-
# Slug Generator
|
|
694
|
-
self.register_tool(ToolDefaultsSpec(
|
|
695
|
-
tool_name="Slug Generator",
|
|
696
|
-
defaults={
|
|
697
|
-
"separator": "-",
|
|
698
|
-
"lowercase": True,
|
|
699
|
-
"transliterate": True,
|
|
700
|
-
"max_length": 0,
|
|
701
|
-
"remove_stopwords": False
|
|
702
|
-
},
|
|
703
|
-
description="URL-friendly slug generation tool"
|
|
704
|
-
))
|
|
705
|
-
|
|
706
|
-
# Column Tools
|
|
707
|
-
self.register_tool(ToolDefaultsSpec(
|
|
708
|
-
tool_name="Column Tools",
|
|
709
|
-
defaults={
|
|
710
|
-
"delimiter": ",",
|
|
711
|
-
"quote_char": "\"",
|
|
712
|
-
"has_header": True
|
|
713
|
-
},
|
|
714
|
-
description="Column and CSV manipulation tool"
|
|
715
|
-
))
|
|
716
|
-
|
|
717
|
-
# Timestamp Converter
|
|
718
|
-
self.register_tool(ToolDefaultsSpec(
|
|
719
|
-
tool_name="Timestamp Converter",
|
|
720
|
-
defaults={
|
|
721
|
-
"input_format": "unix",
|
|
722
|
-
"output_format": "iso",
|
|
723
|
-
"use_utc": False,
|
|
724
|
-
"custom_format": "%Y-%m-%d %H:%M:%S",
|
|
725
|
-
"show_relative": False
|
|
726
|
-
},
|
|
727
|
-
description="Date/time conversion tool"
|
|
728
|
-
))
|
|
729
|
-
|
|
730
|
-
# ASCII Art Generator
|
|
731
|
-
self.register_tool(ToolDefaultsSpec(
|
|
732
|
-
tool_name="ASCII Art Generator",
|
|
733
|
-
defaults={
|
|
734
|
-
"font": "standard",
|
|
735
|
-
"width": 80
|
|
736
|
-
},
|
|
737
|
-
description="Text to ASCII art conversion tool"
|
|
738
|
-
))
|
|
739
|
-
|
|
740
|
-
# Extraction Tools
|
|
741
|
-
self.register_tool(ToolDefaultsSpec(
|
|
742
|
-
tool_name="Extraction Tools",
|
|
743
|
-
defaults={
|
|
744
|
-
"Email Extraction Tool": {"omit_duplicates": False, "hide_counts": True, "sort_emails": False, "only_domain": False},
|
|
745
|
-
"HTML Extraction Tool": {},
|
|
746
|
-
"Regex Extractor": {"pattern": "", "match_mode": "all_per_line", "omit_duplicates": False, "hide_counts": True, "sort_results": False, "case_sensitive": False},
|
|
747
|
-
"URL and Link Extractor": {"extract_href": False, "extract_https": False, "extract_any_protocol": False, "extract_markdown": False, "filter_text": ""}
|
|
748
|
-
},
|
|
749
|
-
description="Text extraction utilities"
|
|
750
|
-
))
|
|
751
|
-
|
|
752
|
-
# Register application-level defaults
|
|
753
|
-
self._register_app_defaults()
|
|
754
|
-
|
|
755
|
-
def _register_app_defaults(self) -> None:
|
|
756
|
-
"""Register application-level default settings."""
|
|
757
|
-
import os
|
|
758
|
-
|
|
759
|
-
default_path = os.path.join(os.path.expanduser('~'), 'Downloads')
|
|
760
|
-
|
|
761
|
-
self._app_defaults = {
|
|
762
|
-
"export_path": default_path,
|
|
763
|
-
"debug_level": "INFO",
|
|
764
|
-
"selected_tool": "Case Tool",
|
|
765
|
-
"active_input_tab": 0,
|
|
766
|
-
"active_output_tab": 0,
|
|
767
|
-
"performance_settings": {
|
|
768
|
-
"mode": "automatic",
|
|
769
|
-
"async_processing": {
|
|
770
|
-
"enabled": True,
|
|
771
|
-
"threshold_kb": 10,
|
|
772
|
-
"max_workers": 2,
|
|
773
|
-
"chunk_size_kb": 50
|
|
774
|
-
},
|
|
775
|
-
"caching": {
|
|
776
|
-
"enabled": True,
|
|
777
|
-
"stats_cache_size": 1000,
|
|
778
|
-
"regex_cache_size": 100,
|
|
779
|
-
"content_cache_size_mb": 50,
|
|
780
|
-
"processing_cache_size": 500
|
|
781
|
-
},
|
|
782
|
-
"memory_management": {
|
|
783
|
-
"enabled": True,
|
|
784
|
-
"gc_optimization": True,
|
|
785
|
-
"memory_pool": True,
|
|
786
|
-
"leak_detection": True,
|
|
787
|
-
"memory_threshold_mb": 500
|
|
788
|
-
},
|
|
789
|
-
"ui_optimizations": {
|
|
790
|
-
"enabled": True,
|
|
791
|
-
"efficient_line_numbers": True,
|
|
792
|
-
"progressive_search": True,
|
|
793
|
-
"debounce_delay_ms": 300,
|
|
794
|
-
"lazy_updates": True
|
|
795
|
-
}
|
|
796
|
-
},
|
|
797
|
-
"font_settings": {
|
|
798
|
-
"text_font": {
|
|
799
|
-
"family": "Source Code Pro",
|
|
800
|
-
"size": 11,
|
|
801
|
-
"fallback_family": "Consolas",
|
|
802
|
-
"fallback_family_mac": "Monaco",
|
|
803
|
-
"fallback_family_linux": "DejaVu Sans Mono"
|
|
804
|
-
},
|
|
805
|
-
"interface_font": {
|
|
806
|
-
"family": "Segoe UI",
|
|
807
|
-
"size": 9,
|
|
808
|
-
"fallback_family": "Arial",
|
|
809
|
-
"fallback_family_mac": "Helvetica",
|
|
810
|
-
"fallback_family_linux": "Ubuntu"
|
|
811
|
-
}
|
|
812
|
-
},
|
|
813
|
-
"dialog_settings": {
|
|
814
|
-
"success": {
|
|
815
|
-
"enabled": True,
|
|
816
|
-
"description": "Success notifications for completed operations",
|
|
817
|
-
"examples": ["File saved successfully", "Settings applied", "Export complete"]
|
|
818
|
-
},
|
|
819
|
-
"confirmation": {
|
|
820
|
-
"enabled": True,
|
|
821
|
-
"description": "Confirmation dialogs for destructive actions",
|
|
822
|
-
"examples": ["Clear all tabs?", "Delete entry?", "Reset settings?"],
|
|
823
|
-
"default_action": "yes"
|
|
824
|
-
},
|
|
825
|
-
"warning": {
|
|
826
|
-
"enabled": True,
|
|
827
|
-
"description": "Warning messages for potential issues",
|
|
828
|
-
"examples": ["No data specified", "Invalid input detected", "Feature unavailable"]
|
|
829
|
-
},
|
|
830
|
-
"error": {
|
|
831
|
-
"enabled": True,
|
|
832
|
-
"locked": True,
|
|
833
|
-
"description": "Error messages for critical issues (cannot be disabled)",
|
|
834
|
-
"examples": ["File not found", "Network error", "Invalid configuration"]
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
def register_tool(self, spec: ToolDefaultsSpec) -> None:
|
|
840
|
-
"""
|
|
841
|
-
Register a tool's default settings.
|
|
842
|
-
|
|
843
|
-
Args:
|
|
844
|
-
spec: ToolDefaultsSpec containing the tool's defaults
|
|
845
|
-
"""
|
|
846
|
-
self._tool_specs[spec.tool_name] = spec
|
|
847
|
-
self.logger.debug(f"Registered defaults for tool: {spec.tool_name}")
|
|
848
|
-
|
|
849
|
-
def unregister_tool(self, tool_name: str) -> bool:
|
|
850
|
-
"""
|
|
851
|
-
Unregister a tool's default settings.
|
|
852
|
-
|
|
853
|
-
Args:
|
|
854
|
-
tool_name: Name of the tool to unregister
|
|
855
|
-
|
|
856
|
-
Returns:
|
|
857
|
-
True if tool was unregistered, False if not found
|
|
858
|
-
"""
|
|
859
|
-
if tool_name in self._tool_specs:
|
|
860
|
-
del self._tool_specs[tool_name]
|
|
861
|
-
self.logger.debug(f"Unregistered defaults for tool: {tool_name}")
|
|
862
|
-
return True
|
|
863
|
-
return False
|
|
864
|
-
|
|
865
|
-
def get_tool_defaults(self, tool_name: str) -> Dict[str, Any]:
|
|
866
|
-
"""
|
|
867
|
-
Get default settings for a specific tool.
|
|
868
|
-
|
|
869
|
-
Args:
|
|
870
|
-
tool_name: Name of the tool
|
|
871
|
-
|
|
872
|
-
Returns:
|
|
873
|
-
Dictionary of default settings, empty dict if tool not found
|
|
874
|
-
"""
|
|
875
|
-
spec = self._tool_specs.get(tool_name)
|
|
876
|
-
if spec:
|
|
877
|
-
return deepcopy(spec.defaults)
|
|
878
|
-
return {}
|
|
879
|
-
|
|
880
|
-
def get_tool_spec(self, tool_name: str) -> Optional[ToolDefaultsSpec]:
|
|
881
|
-
"""
|
|
882
|
-
Get the full specification for a tool.
|
|
883
|
-
|
|
884
|
-
Args:
|
|
885
|
-
tool_name: Name of the tool
|
|
886
|
-
|
|
887
|
-
Returns:
|
|
888
|
-
ToolDefaultsSpec or None if not found
|
|
889
|
-
"""
|
|
890
|
-
return self._tool_specs.get(tool_name)
|
|
891
|
-
|
|
892
|
-
def get_all_tool_defaults(self) -> Dict[str, Dict[str, Any]]:
|
|
893
|
-
"""
|
|
894
|
-
Get all tool default settings.
|
|
895
|
-
|
|
896
|
-
Returns:
|
|
897
|
-
Dictionary mapping tool names to their default settings
|
|
898
|
-
"""
|
|
899
|
-
return {
|
|
900
|
-
name: deepcopy(spec.defaults)
|
|
901
|
-
for name, spec in self._tool_specs.items()
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
def get_all_defaults(self, tab_count: int = 7) -> Dict[str, Any]:
|
|
905
|
-
"""
|
|
906
|
-
Get complete default settings including app-level and all tool defaults.
|
|
907
|
-
|
|
908
|
-
Args:
|
|
909
|
-
tab_count: Number of tabs for input/output (default 7)
|
|
910
|
-
|
|
911
|
-
Returns:
|
|
912
|
-
Complete default settings dictionary
|
|
913
|
-
"""
|
|
914
|
-
defaults = deepcopy(self._app_defaults)
|
|
915
|
-
defaults["input_tabs"] = [""] * tab_count
|
|
916
|
-
defaults["output_tabs"] = [""] * tab_count
|
|
917
|
-
defaults["tool_settings"] = self.get_all_tool_defaults()
|
|
918
|
-
return defaults
|
|
919
|
-
|
|
920
|
-
def get_registered_tools(self) -> List[str]:
|
|
921
|
-
"""
|
|
922
|
-
Get list of all registered tool names.
|
|
923
|
-
|
|
924
|
-
Returns:
|
|
925
|
-
List of tool names
|
|
926
|
-
"""
|
|
927
|
-
return list(self._tool_specs.keys())
|
|
928
|
-
|
|
929
|
-
def validate_settings(self, settings: Dict[str, Any]) -> Tuple[bool, List[str]]:
|
|
930
|
-
"""
|
|
931
|
-
Validate settings against registered schemas.
|
|
932
|
-
|
|
933
|
-
Args:
|
|
934
|
-
settings: Settings dictionary to validate
|
|
935
|
-
|
|
936
|
-
Returns:
|
|
937
|
-
Tuple of (is_valid, list of error messages)
|
|
938
|
-
"""
|
|
939
|
-
errors = []
|
|
940
|
-
|
|
941
|
-
# Check for required app-level keys
|
|
942
|
-
required_app_keys = {"export_path", "debug_level", "selected_tool"}
|
|
943
|
-
for key in required_app_keys:
|
|
944
|
-
if key not in settings:
|
|
945
|
-
errors.append(f"Missing required app setting: {key}")
|
|
946
|
-
|
|
947
|
-
# Validate tool settings
|
|
948
|
-
tool_settings = settings.get("tool_settings", {})
|
|
949
|
-
|
|
950
|
-
for tool_name, spec in self._tool_specs.items():
|
|
951
|
-
if tool_name not in tool_settings:
|
|
952
|
-
# Tool settings missing entirely - not necessarily an error
|
|
953
|
-
# as they will be populated from defaults
|
|
954
|
-
continue
|
|
955
|
-
|
|
956
|
-
tool_config = tool_settings[tool_name]
|
|
957
|
-
|
|
958
|
-
# Check required keys for this tool
|
|
959
|
-
for required_key in spec.required_keys:
|
|
960
|
-
if required_key not in tool_config:
|
|
961
|
-
errors.append(f"Tool '{tool_name}' missing required key: {required_key}")
|
|
962
|
-
|
|
963
|
-
return (len(errors) == 0, errors)
|
|
964
|
-
|
|
965
|
-
def validate_tool_settings(self, tool_name: str, settings: Dict[str, Any]) -> Tuple[bool, List[str]]:
|
|
966
|
-
"""
|
|
967
|
-
Validate settings for a specific tool.
|
|
968
|
-
|
|
969
|
-
Args:
|
|
970
|
-
tool_name: Name of the tool
|
|
971
|
-
settings: Tool settings to validate
|
|
972
|
-
|
|
973
|
-
Returns:
|
|
974
|
-
Tuple of (is_valid, list of error messages)
|
|
975
|
-
"""
|
|
976
|
-
errors = []
|
|
977
|
-
spec = self._tool_specs.get(tool_name)
|
|
978
|
-
|
|
979
|
-
if not spec:
|
|
980
|
-
return (True, []) # Unknown tool, no validation
|
|
981
|
-
|
|
982
|
-
for required_key in spec.required_keys:
|
|
983
|
-
if required_key not in settings:
|
|
984
|
-
errors.append(f"Missing required key: {required_key}")
|
|
985
|
-
|
|
986
|
-
return (len(errors) == 0, errors)
|
|
987
|
-
|
|
988
|
-
def deep_merge(self, base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
|
|
989
|
-
"""
|
|
990
|
-
Deep merge two dictionaries, with override taking precedence.
|
|
991
|
-
|
|
992
|
-
Args:
|
|
993
|
-
base: Base dictionary (defaults)
|
|
994
|
-
override: Override dictionary (user settings)
|
|
995
|
-
|
|
996
|
-
Returns:
|
|
997
|
-
Merged dictionary
|
|
998
|
-
"""
|
|
999
|
-
result = deepcopy(base)
|
|
1000
|
-
|
|
1001
|
-
for key, value in override.items():
|
|
1002
|
-
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
|
1003
|
-
result[key] = self.deep_merge(result[key], value)
|
|
1004
|
-
else:
|
|
1005
|
-
result[key] = deepcopy(value)
|
|
1006
|
-
|
|
1007
|
-
return result
|
|
1008
|
-
|
|
1009
|
-
def merge_with_defaults(self, user_settings: Dict[str, Any], tab_count: int = 7) -> Dict[str, Any]:
|
|
1010
|
-
"""
|
|
1011
|
-
Merge user settings with defaults, filling in any missing values.
|
|
1012
|
-
|
|
1013
|
-
Args:
|
|
1014
|
-
user_settings: User's current settings
|
|
1015
|
-
tab_count: Number of tabs for input/output
|
|
1016
|
-
|
|
1017
|
-
Returns:
|
|
1018
|
-
Complete settings with defaults filled in
|
|
1019
|
-
"""
|
|
1020
|
-
defaults = self.get_all_defaults(tab_count)
|
|
1021
|
-
merged = self.deep_merge(defaults, user_settings)
|
|
1022
|
-
|
|
1023
|
-
# Ensure tool_settings has all registered tools
|
|
1024
|
-
if "tool_settings" not in merged:
|
|
1025
|
-
merged["tool_settings"] = {}
|
|
1026
|
-
|
|
1027
|
-
for tool_name in self._tool_specs:
|
|
1028
|
-
if tool_name not in merged["tool_settings"]:
|
|
1029
|
-
merged["tool_settings"][tool_name] = self.get_tool_defaults(tool_name)
|
|
1030
|
-
else:
|
|
1031
|
-
# Merge tool-specific settings with defaults
|
|
1032
|
-
tool_defaults = self.get_tool_defaults(tool_name)
|
|
1033
|
-
merged["tool_settings"][tool_name] = self.deep_merge(
|
|
1034
|
-
tool_defaults,
|
|
1035
|
-
merged["tool_settings"][tool_name]
|
|
1036
|
-
)
|
|
1037
|
-
|
|
1038
|
-
return merged
|
|
1039
|
-
|
|
1040
|
-
def get_missing_settings(self, settings: Dict[str, Any]) -> Dict[str, Any]:
|
|
1041
|
-
"""
|
|
1042
|
-
Get settings that are missing from the provided settings.
|
|
1043
|
-
|
|
1044
|
-
Args:
|
|
1045
|
-
settings: Current settings to check
|
|
1046
|
-
|
|
1047
|
-
Returns:
|
|
1048
|
-
Dictionary of missing settings with their default values
|
|
1049
|
-
"""
|
|
1050
|
-
defaults = self.get_all_defaults()
|
|
1051
|
-
missing = {}
|
|
1052
|
-
|
|
1053
|
-
def find_missing(default_dict: Dict, current_dict: Dict, path: str = "") -> None:
|
|
1054
|
-
for key, value in default_dict.items():
|
|
1055
|
-
current_path = f"{path}.{key}" if path else key
|
|
1056
|
-
|
|
1057
|
-
if key not in current_dict:
|
|
1058
|
-
missing[current_path] = value
|
|
1059
|
-
elif isinstance(value, dict) and isinstance(current_dict.get(key), dict):
|
|
1060
|
-
find_missing(value, current_dict[key], current_path)
|
|
1061
|
-
|
|
1062
|
-
find_missing(defaults, settings)
|
|
1063
|
-
return missing
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
# Singleton instance for easy access
|
|
1067
|
-
_registry: Optional[SettingsDefaultsRegistry] = None
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
def get_registry() -> SettingsDefaultsRegistry:
|
|
1071
|
-
"""
|
|
1072
|
-
Get the singleton settings defaults registry instance.
|
|
1073
|
-
|
|
1074
|
-
Returns:
|
|
1075
|
-
SettingsDefaultsRegistry instance
|
|
1076
|
-
"""
|
|
1077
|
-
global _registry
|
|
1078
|
-
if _registry is None:
|
|
1079
|
-
_registry = SettingsDefaultsRegistry()
|
|
1080
|
-
return _registry
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
def reset_registry() -> None:
|
|
1084
|
-
"""Reset the registry singleton (mainly for testing)."""
|
|
1085
|
-
global _registry
|
|
1086
|
-
_registry = None
|
|
1087
|
-
SettingsDefaultsRegistry._instance = None
|
|
1
|
+
"""
|
|
2
|
+
Settings Defaults Registry Module
|
|
3
|
+
|
|
4
|
+
Centralizes all tool default settings into a single registry system for consistent
|
|
5
|
+
first-launch initialization. Provides schema validation, deep merge capability,
|
|
6
|
+
and backward compatibility with existing tools.
|
|
7
|
+
|
|
8
|
+
Author: Pomera AI Commander Team
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any, Dict, List, Optional, Callable, Set, Tuple
|
|
13
|
+
from copy import deepcopy
|
|
14
|
+
import logging
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ToolDefaultsSpec:
|
|
19
|
+
"""
|
|
20
|
+
Specification for a tool's default settings.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
tool_name: Unique identifier for the tool (must match key in tool_settings)
|
|
24
|
+
defaults: Dictionary of default settings for the tool
|
|
25
|
+
required_keys: Set of keys that must be present in settings
|
|
26
|
+
description: Human-readable description of the tool
|
|
27
|
+
version: Version of the settings schema (for future migrations)
|
|
28
|
+
"""
|
|
29
|
+
tool_name: str
|
|
30
|
+
defaults: Dict[str, Any]
|
|
31
|
+
required_keys: Set[str] = field(default_factory=set)
|
|
32
|
+
description: str = ""
|
|
33
|
+
version: str = "1.0"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SettingsValidationError(Exception):
|
|
37
|
+
"""Raised when settings validation fails."""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SettingsDefaultsRegistry:
|
|
42
|
+
"""
|
|
43
|
+
Central registry for all tool default settings.
|
|
44
|
+
|
|
45
|
+
This registry provides:
|
|
46
|
+
- Centralized storage of all tool defaults
|
|
47
|
+
- Schema validation for tool settings
|
|
48
|
+
- Deep merge capability for user settings with defaults
|
|
49
|
+
- Backward compatibility with existing tools
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
_instance: Optional['SettingsDefaultsRegistry'] = None
|
|
53
|
+
|
|
54
|
+
def __new__(cls) -> 'SettingsDefaultsRegistry':
|
|
55
|
+
"""Singleton pattern to ensure only one registry exists."""
|
|
56
|
+
if cls._instance is None:
|
|
57
|
+
cls._instance = super().__new__(cls)
|
|
58
|
+
cls._instance._initialized = False
|
|
59
|
+
return cls._instance
|
|
60
|
+
|
|
61
|
+
def __init__(self):
|
|
62
|
+
"""Initialize the registry with default tool specifications."""
|
|
63
|
+
if self._initialized:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
self.logger = logging.getLogger(__name__)
|
|
67
|
+
self._tool_specs: Dict[str, ToolDefaultsSpec] = {}
|
|
68
|
+
self._app_defaults: Dict[str, Any] = {}
|
|
69
|
+
self._initialized = True
|
|
70
|
+
|
|
71
|
+
# Register all built-in tool defaults
|
|
72
|
+
self._register_builtin_defaults()
|
|
73
|
+
|
|
74
|
+
def _register_builtin_defaults(self) -> None:
|
|
75
|
+
"""Register all built-in tool default settings."""
|
|
76
|
+
|
|
77
|
+
# Case Tool - Updated with new exclusions per requirements
|
|
78
|
+
self.register_tool(ToolDefaultsSpec(
|
|
79
|
+
tool_name="Case Tool",
|
|
80
|
+
defaults={
|
|
81
|
+
"mode": "Sentence",
|
|
82
|
+
"exclusions": "a\nan\nthe\nand\nbut\nor\nfor\nnor\non\nat\nto\nfrom\nby\nwith\nin\nof"
|
|
83
|
+
},
|
|
84
|
+
required_keys={"mode"},
|
|
85
|
+
description="Text case conversion tool"
|
|
86
|
+
))
|
|
87
|
+
|
|
88
|
+
# Base64 Encoder/Decoder
|
|
89
|
+
self.register_tool(ToolDefaultsSpec(
|
|
90
|
+
tool_name="Base64 Encoder/Decoder",
|
|
91
|
+
defaults={"mode": "encode"},
|
|
92
|
+
required_keys={"mode"},
|
|
93
|
+
description="Base64 encoding and decoding tool"
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
# JSON/XML Tool
|
|
97
|
+
self.register_tool(ToolDefaultsSpec(
|
|
98
|
+
tool_name="JSON/XML Tool",
|
|
99
|
+
defaults={
|
|
100
|
+
"operation": "json_to_xml",
|
|
101
|
+
"json_indent": 2,
|
|
102
|
+
"xml_indent": 2,
|
|
103
|
+
"preserve_attributes": True,
|
|
104
|
+
"sort_keys": False,
|
|
105
|
+
"array_wrapper": "item",
|
|
106
|
+
"root_element": "root",
|
|
107
|
+
"jsonpath_query": "$",
|
|
108
|
+
"xpath_query": "//*"
|
|
109
|
+
},
|
|
110
|
+
required_keys={"operation"},
|
|
111
|
+
description="JSON and XML conversion tool"
|
|
112
|
+
))
|
|
113
|
+
|
|
114
|
+
# Cron Tool
|
|
115
|
+
self.register_tool(ToolDefaultsSpec(
|
|
116
|
+
tool_name="Cron Tool",
|
|
117
|
+
defaults={
|
|
118
|
+
"action": "parse_explain",
|
|
119
|
+
"preset_category": "Daily Schedules",
|
|
120
|
+
"preset_pattern": "Daily at midnight",
|
|
121
|
+
"compare_expressions": "",
|
|
122
|
+
"next_runs_count": 10
|
|
123
|
+
},
|
|
124
|
+
required_keys={"action"},
|
|
125
|
+
description="Cron expression parser and generator"
|
|
126
|
+
))
|
|
127
|
+
|
|
128
|
+
# Find & Replace Text
|
|
129
|
+
self.register_tool(ToolDefaultsSpec(
|
|
130
|
+
tool_name="Find & Replace Text",
|
|
131
|
+
defaults={
|
|
132
|
+
"find": "",
|
|
133
|
+
"replace": "",
|
|
134
|
+
"mode": "Text",
|
|
135
|
+
"option": "ignore_case",
|
|
136
|
+
"find_history": [],
|
|
137
|
+
"replace_history": []
|
|
138
|
+
},
|
|
139
|
+
required_keys={"mode"},
|
|
140
|
+
description="Find and replace text tool"
|
|
141
|
+
))
|
|
142
|
+
|
|
143
|
+
# Generator Tools
|
|
144
|
+
self.register_tool(ToolDefaultsSpec(
|
|
145
|
+
tool_name="Generator Tools",
|
|
146
|
+
defaults={
|
|
147
|
+
"Strong Password Generator": {
|
|
148
|
+
"length": 20,
|
|
149
|
+
"numbers": "",
|
|
150
|
+
"symbols": ""
|
|
151
|
+
},
|
|
152
|
+
"Repeating Text Generator": {
|
|
153
|
+
"times": 5,
|
|
154
|
+
"separator": "+"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
description="Various text and data generators"
|
|
158
|
+
))
|
|
159
|
+
|
|
160
|
+
# Sorter Tools
|
|
161
|
+
self.register_tool(ToolDefaultsSpec(
|
|
162
|
+
tool_name="Sorter Tools",
|
|
163
|
+
defaults={
|
|
164
|
+
"Number Sorter": {
|
|
165
|
+
"order": "ascending"
|
|
166
|
+
},
|
|
167
|
+
"Alphabetical Sorter": {
|
|
168
|
+
"order": "ascending",
|
|
169
|
+
"unique_only": False,
|
|
170
|
+
"trim": False
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
description="Text and number sorting tools"
|
|
174
|
+
))
|
|
175
|
+
|
|
176
|
+
# URL and Link Extractor
|
|
177
|
+
self.register_tool(ToolDefaultsSpec(
|
|
178
|
+
tool_name="URL and Link Extractor",
|
|
179
|
+
defaults={
|
|
180
|
+
"extract_href": False,
|
|
181
|
+
"extract_https": False,
|
|
182
|
+
"extract_any_protocol": False,
|
|
183
|
+
"extract_markdown": False,
|
|
184
|
+
"filter_text": ""
|
|
185
|
+
},
|
|
186
|
+
description="URL and link extraction tool"
|
|
187
|
+
))
|
|
188
|
+
|
|
189
|
+
# Email Extraction Tool
|
|
190
|
+
self.register_tool(ToolDefaultsSpec(
|
|
191
|
+
tool_name="Email Extraction Tool",
|
|
192
|
+
defaults={
|
|
193
|
+
"omit_duplicates": False,
|
|
194
|
+
"hide_counts": True,
|
|
195
|
+
"sort_emails": False,
|
|
196
|
+
"only_domain": False
|
|
197
|
+
},
|
|
198
|
+
description="Email address extraction tool"
|
|
199
|
+
))
|
|
200
|
+
|
|
201
|
+
# Regex Extractor
|
|
202
|
+
self.register_tool(ToolDefaultsSpec(
|
|
203
|
+
tool_name="Regex Extractor",
|
|
204
|
+
defaults={
|
|
205
|
+
"pattern": "",
|
|
206
|
+
"match_mode": "all_per_line",
|
|
207
|
+
"omit_duplicates": False,
|
|
208
|
+
"hide_counts": True,
|
|
209
|
+
"sort_results": False,
|
|
210
|
+
"case_sensitive": False
|
|
211
|
+
},
|
|
212
|
+
required_keys={"match_mode"},
|
|
213
|
+
description="Regular expression extraction tool"
|
|
214
|
+
))
|
|
215
|
+
|
|
216
|
+
# Email Header Analyzer
|
|
217
|
+
self.register_tool(ToolDefaultsSpec(
|
|
218
|
+
tool_name="Email Header Analyzer",
|
|
219
|
+
defaults={
|
|
220
|
+
"show_timestamps": True,
|
|
221
|
+
"show_delays": True,
|
|
222
|
+
"show_authentication": True,
|
|
223
|
+
"show_spam_score": True
|
|
224
|
+
},
|
|
225
|
+
description="Email header analysis tool"
|
|
226
|
+
))
|
|
227
|
+
|
|
228
|
+
# Folder File Reporter
|
|
229
|
+
self.register_tool(ToolDefaultsSpec(
|
|
230
|
+
tool_name="Folder File Reporter",
|
|
231
|
+
defaults={
|
|
232
|
+
"last_input_folder": "",
|
|
233
|
+
"last_output_folder": "",
|
|
234
|
+
"field_selections": {
|
|
235
|
+
"path": True,
|
|
236
|
+
"name": True,
|
|
237
|
+
"size": True,
|
|
238
|
+
"date_modified": True
|
|
239
|
+
},
|
|
240
|
+
"separator": " | ",
|
|
241
|
+
"folders_only": False,
|
|
242
|
+
"recursion_mode": "full",
|
|
243
|
+
"recursion_depth": 2,
|
|
244
|
+
"size_format": "human",
|
|
245
|
+
"date_format": "%Y-%m-%d %H:%M:%S"
|
|
246
|
+
},
|
|
247
|
+
description="Folder and file reporting tool"
|
|
248
|
+
))
|
|
249
|
+
|
|
250
|
+
# URL Parser
|
|
251
|
+
self.register_tool(ToolDefaultsSpec(
|
|
252
|
+
tool_name="URL Parser",
|
|
253
|
+
defaults={"ascii_decode": True},
|
|
254
|
+
description="URL parsing and analysis tool"
|
|
255
|
+
))
|
|
256
|
+
|
|
257
|
+
# Word Frequency Counter
|
|
258
|
+
self.register_tool(ToolDefaultsSpec(
|
|
259
|
+
tool_name="Word Frequency Counter",
|
|
260
|
+
defaults={},
|
|
261
|
+
description="Word frequency analysis tool"
|
|
262
|
+
))
|
|
263
|
+
|
|
264
|
+
# Google AI - Updated December 2025
|
|
265
|
+
# Latest: Gemini 2.5 series (Pro, Flash, Flash-Lite), Gemini 2.0 series
|
|
266
|
+
self.register_tool(ToolDefaultsSpec(
|
|
267
|
+
tool_name="Google AI",
|
|
268
|
+
defaults={
|
|
269
|
+
"API_KEY": "putinyourkey",
|
|
270
|
+
"MODEL": "gemini-2.5-pro",
|
|
271
|
+
"MODELS_LIST": [
|
|
272
|
+
"gemini-2.5-pro",
|
|
273
|
+
"gemini-2.5-flash",
|
|
274
|
+
"gemini-2.5-flash-lite",
|
|
275
|
+
"gemini-2.0-flash",
|
|
276
|
+
"gemini-2.0-flash-lite",
|
|
277
|
+
"gemini-1.5-pro-latest",
|
|
278
|
+
"gemini-1.5-flash-latest"
|
|
279
|
+
],
|
|
280
|
+
"system_prompt": "You are a helpful assistant.",
|
|
281
|
+
"temperature": 0.7,
|
|
282
|
+
"topK": 40,
|
|
283
|
+
"topP": 0.95,
|
|
284
|
+
"candidateCount": 1,
|
|
285
|
+
"maxOutputTokens": 8192,
|
|
286
|
+
"stopSequences": ""
|
|
287
|
+
},
|
|
288
|
+
required_keys={"API_KEY", "MODEL"},
|
|
289
|
+
description="Google AI (Gemini) integration"
|
|
290
|
+
))
|
|
291
|
+
|
|
292
|
+
# Azure AI - Updated December 2025
|
|
293
|
+
# Latest: GPT-4.1 series (4.1, 4.1-mini, 4.1-nano), GPT-4o being retired Feb 2026
|
|
294
|
+
self.register_tool(ToolDefaultsSpec(
|
|
295
|
+
tool_name="Azure AI",
|
|
296
|
+
defaults={
|
|
297
|
+
"API_KEY": "putinyourkey",
|
|
298
|
+
"MODEL": "gpt-4.1",
|
|
299
|
+
"MODELS_LIST": [
|
|
300
|
+
"gpt-4.1",
|
|
301
|
+
"gpt-4.1-mini",
|
|
302
|
+
"gpt-4.1-nano",
|
|
303
|
+
"gpt-4o",
|
|
304
|
+
"gpt-4o-mini",
|
|
305
|
+
"gpt-4-turbo"
|
|
306
|
+
],
|
|
307
|
+
"ENDPOINT": "",
|
|
308
|
+
"API_VERSION": "2024-10-21",
|
|
309
|
+
"system_prompt": "You are a helpful assistant.",
|
|
310
|
+
"temperature": 0.7,
|
|
311
|
+
"max_tokens": 4096,
|
|
312
|
+
"top_p": 1.0,
|
|
313
|
+
"frequency_penalty": 0.0,
|
|
314
|
+
"presence_penalty": 0.0,
|
|
315
|
+
"seed": "",
|
|
316
|
+
"stop": ""
|
|
317
|
+
},
|
|
318
|
+
required_keys={"API_KEY", "MODEL", "ENDPOINT"},
|
|
319
|
+
description="Azure OpenAI integration"
|
|
320
|
+
))
|
|
321
|
+
|
|
322
|
+
# Anthropic AI - Updated December 2025
|
|
323
|
+
# Latest: Claude 4 series (Opus 4.5, Sonnet 4.5, Sonnet 4, Opus 4)
|
|
324
|
+
self.register_tool(ToolDefaultsSpec(
|
|
325
|
+
tool_name="Anthropic AI",
|
|
326
|
+
defaults={
|
|
327
|
+
"API_KEY": "putinyourkey",
|
|
328
|
+
"MODEL": "claude-sonnet-4-5-20250929",
|
|
329
|
+
"MODELS_LIST": [
|
|
330
|
+
"claude-sonnet-4-5-20250929",
|
|
331
|
+
"claude-opus-4-5-20251124",
|
|
332
|
+
"claude-sonnet-4-20250522",
|
|
333
|
+
"claude-opus-4-20250522",
|
|
334
|
+
"claude-3-5-sonnet-20241022",
|
|
335
|
+
"claude-3-5-haiku-20241022",
|
|
336
|
+
"claude-3-opus-20240229"
|
|
337
|
+
],
|
|
338
|
+
"system": "You are a helpful assistant.",
|
|
339
|
+
"max_tokens": 4096,
|
|
340
|
+
"temperature": 0.7,
|
|
341
|
+
"top_p": 0.9,
|
|
342
|
+
"top_k": 40,
|
|
343
|
+
"stop_sequences": ""
|
|
344
|
+
},
|
|
345
|
+
required_keys={"API_KEY", "MODEL"},
|
|
346
|
+
description="Anthropic Claude AI integration"
|
|
347
|
+
))
|
|
348
|
+
|
|
349
|
+
# OpenAI - Updated December 2025
|
|
350
|
+
# Latest: GPT-4.1 series, GPT-4o being retired Feb 2026
|
|
351
|
+
self.register_tool(ToolDefaultsSpec(
|
|
352
|
+
tool_name="OpenAI",
|
|
353
|
+
defaults={
|
|
354
|
+
"API_KEY": "putinyourkey",
|
|
355
|
+
"MODEL": "gpt-4.1",
|
|
356
|
+
"MODELS_LIST": [
|
|
357
|
+
"gpt-4.1",
|
|
358
|
+
"gpt-4.1-mini",
|
|
359
|
+
"gpt-4.1-nano",
|
|
360
|
+
"gpt-4o",
|
|
361
|
+
"gpt-4o-mini",
|
|
362
|
+
"gpt-4-turbo",
|
|
363
|
+
"o1-preview",
|
|
364
|
+
"o1-mini"
|
|
365
|
+
],
|
|
366
|
+
"system_prompt": "You are a helpful assistant.",
|
|
367
|
+
"temperature": 0.7,
|
|
368
|
+
"max_tokens": 4096,
|
|
369
|
+
"top_p": 1.0,
|
|
370
|
+
"frequency_penalty": 0.0,
|
|
371
|
+
"presence_penalty": 0.0,
|
|
372
|
+
"seed": "",
|
|
373
|
+
"response_format": "text",
|
|
374
|
+
"stop": ""
|
|
375
|
+
},
|
|
376
|
+
required_keys={"API_KEY", "MODEL"},
|
|
377
|
+
description="OpenAI GPT integration"
|
|
378
|
+
))
|
|
379
|
+
|
|
380
|
+
# Cohere AI - Updated December 2025
|
|
381
|
+
# Latest: Command A (March 2025), Command R+ (08-2024), Command R (08-2024)
|
|
382
|
+
self.register_tool(ToolDefaultsSpec(
|
|
383
|
+
tool_name="Cohere AI",
|
|
384
|
+
defaults={
|
|
385
|
+
"API_KEY": "putinyourkey",
|
|
386
|
+
"MODEL": "command-a-03-2025",
|
|
387
|
+
"MODELS_LIST": [
|
|
388
|
+
"command-a-03-2025",
|
|
389
|
+
"command-r-plus-08-2024",
|
|
390
|
+
"command-r-08-2024",
|
|
391
|
+
"command-r-plus",
|
|
392
|
+
"command-r",
|
|
393
|
+
"command-light"
|
|
394
|
+
],
|
|
395
|
+
"preamble": "You are a helpful assistant.",
|
|
396
|
+
"temperature": 0.7,
|
|
397
|
+
"max_tokens": 4000,
|
|
398
|
+
"k": 50,
|
|
399
|
+
"p": 0.75,
|
|
400
|
+
"frequency_penalty": 0.0,
|
|
401
|
+
"presence_penalty": 0.0,
|
|
402
|
+
"stop_sequences": "",
|
|
403
|
+
"citation_quality": "accurate"
|
|
404
|
+
},
|
|
405
|
+
required_keys={"API_KEY", "MODEL"},
|
|
406
|
+
description="Cohere AI integration"
|
|
407
|
+
))
|
|
408
|
+
|
|
409
|
+
# HuggingFace AI - Updated December 2025
|
|
410
|
+
# Latest: Llama 3.3, Mistral Small 3, Qwen 2.5
|
|
411
|
+
self.register_tool(ToolDefaultsSpec(
|
|
412
|
+
tool_name="HuggingFace AI",
|
|
413
|
+
defaults={
|
|
414
|
+
"API_KEY": "putinyourkey",
|
|
415
|
+
"MODEL": "meta-llama/Llama-3.3-70B-Instruct",
|
|
416
|
+
"MODELS_LIST": [
|
|
417
|
+
"meta-llama/Llama-3.3-70B-Instruct",
|
|
418
|
+
"meta-llama/Meta-Llama-3.1-70B-Instruct",
|
|
419
|
+
"meta-llama/Meta-Llama-3.1-8B-Instruct",
|
|
420
|
+
"mistralai/Mistral-Small-3-Instruct",
|
|
421
|
+
"mistralai/Mistral-7B-Instruct-v0.3",
|
|
422
|
+
"Qwen/Qwen2.5-72B-Instruct",
|
|
423
|
+
"google/gemma-2-27b-it"
|
|
424
|
+
],
|
|
425
|
+
"system_prompt": "You are a helpful assistant.",
|
|
426
|
+
"max_tokens": 4096,
|
|
427
|
+
"temperature": 0.7,
|
|
428
|
+
"top_p": 0.95,
|
|
429
|
+
"stop_sequences": "",
|
|
430
|
+
"seed": ""
|
|
431
|
+
},
|
|
432
|
+
required_keys={"API_KEY", "MODEL"},
|
|
433
|
+
description="HuggingFace AI integration"
|
|
434
|
+
))
|
|
435
|
+
|
|
436
|
+
# Groq AI - Updated December 2025
|
|
437
|
+
# Latest: Llama 3.3 70B, Mixtral 8x7B, Gemma 2
|
|
438
|
+
self.register_tool(ToolDefaultsSpec(
|
|
439
|
+
tool_name="Groq AI",
|
|
440
|
+
defaults={
|
|
441
|
+
"API_KEY": "putinyourkey",
|
|
442
|
+
"MODEL": "llama-3.3-70b-versatile",
|
|
443
|
+
"MODELS_LIST": [
|
|
444
|
+
"llama-3.3-70b-versatile",
|
|
445
|
+
"llama-3.1-70b-versatile",
|
|
446
|
+
"llama-3.1-8b-instant",
|
|
447
|
+
"mixtral-8x7b-32768",
|
|
448
|
+
"gemma2-9b-it",
|
|
449
|
+
"llama-guard-3-8b"
|
|
450
|
+
],
|
|
451
|
+
"system_prompt": "You are a helpful assistant.",
|
|
452
|
+
"temperature": 0.7,
|
|
453
|
+
"max_tokens": 8192,
|
|
454
|
+
"top_p": 1.0,
|
|
455
|
+
"frequency_penalty": 0.0,
|
|
456
|
+
"presence_penalty": 0.0,
|
|
457
|
+
"stop": "",
|
|
458
|
+
"seed": "",
|
|
459
|
+
"response_format": "text"
|
|
460
|
+
},
|
|
461
|
+
required_keys={"API_KEY", "MODEL"},
|
|
462
|
+
description="Groq AI integration"
|
|
463
|
+
))
|
|
464
|
+
|
|
465
|
+
# OpenRouterAI - Updated December 2025
|
|
466
|
+
# Latest: Claude Opus 4.5, GPT-4.1, Gemini 2.5, DeepSeek 3.2
|
|
467
|
+
self.register_tool(ToolDefaultsSpec(
|
|
468
|
+
tool_name="OpenRouterAI",
|
|
469
|
+
defaults={
|
|
470
|
+
"API_KEY": "putinyourkey",
|
|
471
|
+
"MODEL": "anthropic/claude-sonnet-4.5",
|
|
472
|
+
"MODELS_LIST": [
|
|
473
|
+
"anthropic/claude-sonnet-4.5",
|
|
474
|
+
"anthropic/claude-opus-4.5",
|
|
475
|
+
"openai/gpt-4.1",
|
|
476
|
+
"google/gemini-2.5-pro",
|
|
477
|
+
"google/gemini-2.5-flash",
|
|
478
|
+
"deepseek/deepseek-chat",
|
|
479
|
+
"meta-llama/llama-3.3-70b-instruct",
|
|
480
|
+
"google/gemini-2.0-flash:free",
|
|
481
|
+
"meta-llama/llama-3.1-8b-instruct:free"
|
|
482
|
+
],
|
|
483
|
+
"system_prompt": "You are a helpful assistant.",
|
|
484
|
+
"temperature": 0.7,
|
|
485
|
+
"max_tokens": 4096,
|
|
486
|
+
"top_p": 1.0,
|
|
487
|
+
"top_k": 0,
|
|
488
|
+
"frequency_penalty": 0.0,
|
|
489
|
+
"presence_penalty": 0.0,
|
|
490
|
+
"repetition_penalty": 1.0,
|
|
491
|
+
"seed": "",
|
|
492
|
+
"stop": ""
|
|
493
|
+
},
|
|
494
|
+
required_keys={"API_KEY", "MODEL"},
|
|
495
|
+
description="OpenRouter AI integration"
|
|
496
|
+
))
|
|
497
|
+
|
|
498
|
+
# AWS Bedrock - Updated December 2025
|
|
499
|
+
# Latest: Claude 3.5 Sonnet v2, Claude 3.5 Haiku, Llama 3.2, Titan G1
|
|
500
|
+
self.register_tool(ToolDefaultsSpec(
|
|
501
|
+
tool_name="AWS Bedrock",
|
|
502
|
+
defaults={
|
|
503
|
+
"ACCESS_KEY": "",
|
|
504
|
+
"SECRET_KEY": "",
|
|
505
|
+
"REGION": "us-east-1",
|
|
506
|
+
"MODEL": "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
507
|
+
"MODELS_LIST": [
|
|
508
|
+
"anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
509
|
+
"anthropic.claude-3-5-haiku-20241022-v1:0",
|
|
510
|
+
"anthropic.claude-3-opus-20240229-v1:0",
|
|
511
|
+
"anthropic.claude-3-sonnet-20240229-v1:0",
|
|
512
|
+
"meta.llama3-2-90b-instruct-v1:0",
|
|
513
|
+
"meta.llama3-2-11b-instruct-v1:0",
|
|
514
|
+
"meta.llama3-1-70b-instruct-v1:0",
|
|
515
|
+
"meta.llama3-1-8b-instruct-v1:0",
|
|
516
|
+
"amazon.titan-text-premier-v1:0",
|
|
517
|
+
"amazon.titan-text-express-v1",
|
|
518
|
+
"mistral.mixtral-8x7b-instruct-v0:1"
|
|
519
|
+
],
|
|
520
|
+
"system_prompt": "You are a helpful assistant.",
|
|
521
|
+
"temperature": 0.7,
|
|
522
|
+
"max_tokens": 4096,
|
|
523
|
+
"top_p": 0.9,
|
|
524
|
+
"top_k": 40
|
|
525
|
+
},
|
|
526
|
+
required_keys={"ACCESS_KEY", "SECRET_KEY", "REGION", "MODEL"},
|
|
527
|
+
description="AWS Bedrock AI integration"
|
|
528
|
+
))
|
|
529
|
+
|
|
530
|
+
# Vertex AI - Updated December 2025
|
|
531
|
+
# Latest: Gemini 2.5 series (Pro, Flash, Flash-Lite)
|
|
532
|
+
self.register_tool(ToolDefaultsSpec(
|
|
533
|
+
tool_name="Vertex AI",
|
|
534
|
+
defaults={
|
|
535
|
+
"PROJECT_ID": "",
|
|
536
|
+
"LOCATION": "us-central1",
|
|
537
|
+
"MODEL": "gemini-2.5-pro",
|
|
538
|
+
"MODELS_LIST": [
|
|
539
|
+
"gemini-2.5-pro",
|
|
540
|
+
"gemini-2.5-flash",
|
|
541
|
+
"gemini-2.5-flash-lite",
|
|
542
|
+
"gemini-2.0-flash",
|
|
543
|
+
"gemini-2.0-flash-lite",
|
|
544
|
+
"gemini-1.5-pro",
|
|
545
|
+
"gemini-1.5-flash"
|
|
546
|
+
],
|
|
547
|
+
"system_prompt": "You are a helpful assistant.",
|
|
548
|
+
"temperature": 0.7,
|
|
549
|
+
"max_tokens": 8192,
|
|
550
|
+
"top_p": 0.95,
|
|
551
|
+
"top_k": 40
|
|
552
|
+
},
|
|
553
|
+
required_keys={"PROJECT_ID", "LOCATION", "MODEL"},
|
|
554
|
+
description="Google Vertex AI integration"
|
|
555
|
+
))
|
|
556
|
+
|
|
557
|
+
# AI Tools (managed by AIToolsWidget)
|
|
558
|
+
self.register_tool(ToolDefaultsSpec(
|
|
559
|
+
tool_name="AI Tools",
|
|
560
|
+
defaults={},
|
|
561
|
+
description="AI Tools settings managed by AIToolsWidget"
|
|
562
|
+
))
|
|
563
|
+
|
|
564
|
+
# Diff Viewer
|
|
565
|
+
self.register_tool(ToolDefaultsSpec(
|
|
566
|
+
tool_name="Diff Viewer",
|
|
567
|
+
defaults={"option": "ignore_case"},
|
|
568
|
+
description="Text diff comparison tool"
|
|
569
|
+
))
|
|
570
|
+
|
|
571
|
+
# List Comparator
|
|
572
|
+
self.register_tool(ToolDefaultsSpec(
|
|
573
|
+
tool_name="List Comparator",
|
|
574
|
+
defaults={
|
|
575
|
+
"operation": "unique_to_first",
|
|
576
|
+
"case_sensitive": False,
|
|
577
|
+
"trim_whitespace": True
|
|
578
|
+
},
|
|
579
|
+
description="List comparison tool"
|
|
580
|
+
))
|
|
581
|
+
|
|
582
|
+
# HTML Tool
|
|
583
|
+
self.register_tool(ToolDefaultsSpec(
|
|
584
|
+
tool_name="HTML Tool",
|
|
585
|
+
defaults={
|
|
586
|
+
"operation": "strip_tags",
|
|
587
|
+
"preserve_links": False,
|
|
588
|
+
"preserve_images": False
|
|
589
|
+
},
|
|
590
|
+
description="HTML processing tool"
|
|
591
|
+
))
|
|
592
|
+
|
|
593
|
+
# Line Tools
|
|
594
|
+
self.register_tool(ToolDefaultsSpec(
|
|
595
|
+
tool_name="Line Tools",
|
|
596
|
+
defaults={
|
|
597
|
+
"duplicate_mode": "keep_first",
|
|
598
|
+
"case_sensitive": True,
|
|
599
|
+
"preserve_single": False,
|
|
600
|
+
"number_format": "1. ",
|
|
601
|
+
"start_number": 1,
|
|
602
|
+
"skip_empty": False
|
|
603
|
+
},
|
|
604
|
+
required_keys={"duplicate_mode"},
|
|
605
|
+
description="Line manipulation utilities"
|
|
606
|
+
))
|
|
607
|
+
|
|
608
|
+
# Whitespace Tools
|
|
609
|
+
self.register_tool(ToolDefaultsSpec(
|
|
610
|
+
tool_name="Whitespace Tools",
|
|
611
|
+
defaults={
|
|
612
|
+
"trim_mode": "both",
|
|
613
|
+
"preserve_indent": False,
|
|
614
|
+
"tab_size": 4,
|
|
615
|
+
"line_ending": "lf"
|
|
616
|
+
},
|
|
617
|
+
description="Whitespace manipulation utilities"
|
|
618
|
+
))
|
|
619
|
+
|
|
620
|
+
# Text Statistics
|
|
621
|
+
self.register_tool(ToolDefaultsSpec(
|
|
622
|
+
tool_name="Text Statistics",
|
|
623
|
+
defaults={
|
|
624
|
+
"words_per_minute": 200,
|
|
625
|
+
"show_frequency": True,
|
|
626
|
+
"frequency_count": 10
|
|
627
|
+
},
|
|
628
|
+
description="Comprehensive text analysis tool"
|
|
629
|
+
))
|
|
630
|
+
|
|
631
|
+
# Hash Generator
|
|
632
|
+
self.register_tool(ToolDefaultsSpec(
|
|
633
|
+
tool_name="Hash Generator",
|
|
634
|
+
defaults={
|
|
635
|
+
"algorithms": ["md5", "sha256"],
|
|
636
|
+
"uppercase": False
|
|
637
|
+
},
|
|
638
|
+
description="Cryptographic hash generation tool"
|
|
639
|
+
))
|
|
640
|
+
|
|
641
|
+
# Markdown Tools
|
|
642
|
+
self.register_tool(ToolDefaultsSpec(
|
|
643
|
+
tool_name="Markdown Tools",
|
|
644
|
+
defaults={
|
|
645
|
+
"preserve_links_text": True,
|
|
646
|
+
"include_images": False,
|
|
647
|
+
"header_format": "indented",
|
|
648
|
+
"csv_delimiter": ","
|
|
649
|
+
},
|
|
650
|
+
description="Markdown processing utilities"
|
|
651
|
+
))
|
|
652
|
+
|
|
653
|
+
# String Escape Tool
|
|
654
|
+
self.register_tool(ToolDefaultsSpec(
|
|
655
|
+
tool_name="String Escape Tool",
|
|
656
|
+
defaults={
|
|
657
|
+
"format": "json",
|
|
658
|
+
"mode": "escape",
|
|
659
|
+
"plus_spaces": False
|
|
660
|
+
},
|
|
661
|
+
description="String escape/unescape utilities"
|
|
662
|
+
))
|
|
663
|
+
|
|
664
|
+
# Number Base Converter
|
|
665
|
+
self.register_tool(ToolDefaultsSpec(
|
|
666
|
+
tool_name="Number Base Converter",
|
|
667
|
+
defaults={
|
|
668
|
+
"input_base": "decimal",
|
|
669
|
+
"output_base": "hex",
|
|
670
|
+
"uppercase": True,
|
|
671
|
+
"show_prefix": True
|
|
672
|
+
},
|
|
673
|
+
description="Number base conversion tool"
|
|
674
|
+
))
|
|
675
|
+
|
|
676
|
+
# Text Wrapper
|
|
677
|
+
self.register_tool(ToolDefaultsSpec(
|
|
678
|
+
tool_name="Text Wrapper",
|
|
679
|
+
defaults={
|
|
680
|
+
"wrap_width": 80,
|
|
681
|
+
"justify_mode": "left",
|
|
682
|
+
"justify_width": 80,
|
|
683
|
+
"prefix": "",
|
|
684
|
+
"suffix": "",
|
|
685
|
+
"skip_empty": True,
|
|
686
|
+
"indent_size": 4,
|
|
687
|
+
"indent_char": "space",
|
|
688
|
+
"quote_style": "double"
|
|
689
|
+
},
|
|
690
|
+
description="Text wrapping and formatting tool"
|
|
691
|
+
))
|
|
692
|
+
|
|
693
|
+
# Slug Generator
|
|
694
|
+
self.register_tool(ToolDefaultsSpec(
|
|
695
|
+
tool_name="Slug Generator",
|
|
696
|
+
defaults={
|
|
697
|
+
"separator": "-",
|
|
698
|
+
"lowercase": True,
|
|
699
|
+
"transliterate": True,
|
|
700
|
+
"max_length": 0,
|
|
701
|
+
"remove_stopwords": False
|
|
702
|
+
},
|
|
703
|
+
description="URL-friendly slug generation tool"
|
|
704
|
+
))
|
|
705
|
+
|
|
706
|
+
# Column Tools
|
|
707
|
+
self.register_tool(ToolDefaultsSpec(
|
|
708
|
+
tool_name="Column Tools",
|
|
709
|
+
defaults={
|
|
710
|
+
"delimiter": ",",
|
|
711
|
+
"quote_char": "\"",
|
|
712
|
+
"has_header": True
|
|
713
|
+
},
|
|
714
|
+
description="Column and CSV manipulation tool"
|
|
715
|
+
))
|
|
716
|
+
|
|
717
|
+
# Timestamp Converter
|
|
718
|
+
self.register_tool(ToolDefaultsSpec(
|
|
719
|
+
tool_name="Timestamp Converter",
|
|
720
|
+
defaults={
|
|
721
|
+
"input_format": "unix",
|
|
722
|
+
"output_format": "iso",
|
|
723
|
+
"use_utc": False,
|
|
724
|
+
"custom_format": "%Y-%m-%d %H:%M:%S",
|
|
725
|
+
"show_relative": False
|
|
726
|
+
},
|
|
727
|
+
description="Date/time conversion tool"
|
|
728
|
+
))
|
|
729
|
+
|
|
730
|
+
# ASCII Art Generator
|
|
731
|
+
self.register_tool(ToolDefaultsSpec(
|
|
732
|
+
tool_name="ASCII Art Generator",
|
|
733
|
+
defaults={
|
|
734
|
+
"font": "standard",
|
|
735
|
+
"width": 80
|
|
736
|
+
},
|
|
737
|
+
description="Text to ASCII art conversion tool"
|
|
738
|
+
))
|
|
739
|
+
|
|
740
|
+
# Extraction Tools
|
|
741
|
+
self.register_tool(ToolDefaultsSpec(
|
|
742
|
+
tool_name="Extraction Tools",
|
|
743
|
+
defaults={
|
|
744
|
+
"Email Extraction Tool": {"omit_duplicates": False, "hide_counts": True, "sort_emails": False, "only_domain": False},
|
|
745
|
+
"HTML Extraction Tool": {},
|
|
746
|
+
"Regex Extractor": {"pattern": "", "match_mode": "all_per_line", "omit_duplicates": False, "hide_counts": True, "sort_results": False, "case_sensitive": False},
|
|
747
|
+
"URL and Link Extractor": {"extract_href": False, "extract_https": False, "extract_any_protocol": False, "extract_markdown": False, "filter_text": ""}
|
|
748
|
+
},
|
|
749
|
+
description="Text extraction utilities"
|
|
750
|
+
))
|
|
751
|
+
|
|
752
|
+
# Register application-level defaults
|
|
753
|
+
self._register_app_defaults()
|
|
754
|
+
|
|
755
|
+
def _register_app_defaults(self) -> None:
|
|
756
|
+
"""Register application-level default settings."""
|
|
757
|
+
import os
|
|
758
|
+
|
|
759
|
+
default_path = os.path.join(os.path.expanduser('~'), 'Downloads')
|
|
760
|
+
|
|
761
|
+
self._app_defaults = {
|
|
762
|
+
"export_path": default_path,
|
|
763
|
+
"debug_level": "INFO",
|
|
764
|
+
"selected_tool": "Case Tool",
|
|
765
|
+
"active_input_tab": 0,
|
|
766
|
+
"active_output_tab": 0,
|
|
767
|
+
"performance_settings": {
|
|
768
|
+
"mode": "automatic",
|
|
769
|
+
"async_processing": {
|
|
770
|
+
"enabled": True,
|
|
771
|
+
"threshold_kb": 10,
|
|
772
|
+
"max_workers": 2,
|
|
773
|
+
"chunk_size_kb": 50
|
|
774
|
+
},
|
|
775
|
+
"caching": {
|
|
776
|
+
"enabled": True,
|
|
777
|
+
"stats_cache_size": 1000,
|
|
778
|
+
"regex_cache_size": 100,
|
|
779
|
+
"content_cache_size_mb": 50,
|
|
780
|
+
"processing_cache_size": 500
|
|
781
|
+
},
|
|
782
|
+
"memory_management": {
|
|
783
|
+
"enabled": True,
|
|
784
|
+
"gc_optimization": True,
|
|
785
|
+
"memory_pool": True,
|
|
786
|
+
"leak_detection": True,
|
|
787
|
+
"memory_threshold_mb": 500
|
|
788
|
+
},
|
|
789
|
+
"ui_optimizations": {
|
|
790
|
+
"enabled": True,
|
|
791
|
+
"efficient_line_numbers": True,
|
|
792
|
+
"progressive_search": True,
|
|
793
|
+
"debounce_delay_ms": 300,
|
|
794
|
+
"lazy_updates": True
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
"font_settings": {
|
|
798
|
+
"text_font": {
|
|
799
|
+
"family": "Source Code Pro",
|
|
800
|
+
"size": 11,
|
|
801
|
+
"fallback_family": "Consolas",
|
|
802
|
+
"fallback_family_mac": "Monaco",
|
|
803
|
+
"fallback_family_linux": "DejaVu Sans Mono"
|
|
804
|
+
},
|
|
805
|
+
"interface_font": {
|
|
806
|
+
"family": "Segoe UI",
|
|
807
|
+
"size": 9,
|
|
808
|
+
"fallback_family": "Arial",
|
|
809
|
+
"fallback_family_mac": "Helvetica",
|
|
810
|
+
"fallback_family_linux": "Ubuntu"
|
|
811
|
+
}
|
|
812
|
+
},
|
|
813
|
+
"dialog_settings": {
|
|
814
|
+
"success": {
|
|
815
|
+
"enabled": True,
|
|
816
|
+
"description": "Success notifications for completed operations",
|
|
817
|
+
"examples": ["File saved successfully", "Settings applied", "Export complete"]
|
|
818
|
+
},
|
|
819
|
+
"confirmation": {
|
|
820
|
+
"enabled": True,
|
|
821
|
+
"description": "Confirmation dialogs for destructive actions",
|
|
822
|
+
"examples": ["Clear all tabs?", "Delete entry?", "Reset settings?"],
|
|
823
|
+
"default_action": "yes"
|
|
824
|
+
},
|
|
825
|
+
"warning": {
|
|
826
|
+
"enabled": True,
|
|
827
|
+
"description": "Warning messages for potential issues",
|
|
828
|
+
"examples": ["No data specified", "Invalid input detected", "Feature unavailable"]
|
|
829
|
+
},
|
|
830
|
+
"error": {
|
|
831
|
+
"enabled": True,
|
|
832
|
+
"locked": True,
|
|
833
|
+
"description": "Error messages for critical issues (cannot be disabled)",
|
|
834
|
+
"examples": ["File not found", "Network error", "Invalid configuration"]
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
def register_tool(self, spec: ToolDefaultsSpec) -> None:
|
|
840
|
+
"""
|
|
841
|
+
Register a tool's default settings.
|
|
842
|
+
|
|
843
|
+
Args:
|
|
844
|
+
spec: ToolDefaultsSpec containing the tool's defaults
|
|
845
|
+
"""
|
|
846
|
+
self._tool_specs[spec.tool_name] = spec
|
|
847
|
+
self.logger.debug(f"Registered defaults for tool: {spec.tool_name}")
|
|
848
|
+
|
|
849
|
+
def unregister_tool(self, tool_name: str) -> bool:
|
|
850
|
+
"""
|
|
851
|
+
Unregister a tool's default settings.
|
|
852
|
+
|
|
853
|
+
Args:
|
|
854
|
+
tool_name: Name of the tool to unregister
|
|
855
|
+
|
|
856
|
+
Returns:
|
|
857
|
+
True if tool was unregistered, False if not found
|
|
858
|
+
"""
|
|
859
|
+
if tool_name in self._tool_specs:
|
|
860
|
+
del self._tool_specs[tool_name]
|
|
861
|
+
self.logger.debug(f"Unregistered defaults for tool: {tool_name}")
|
|
862
|
+
return True
|
|
863
|
+
return False
|
|
864
|
+
|
|
865
|
+
def get_tool_defaults(self, tool_name: str) -> Dict[str, Any]:
|
|
866
|
+
"""
|
|
867
|
+
Get default settings for a specific tool.
|
|
868
|
+
|
|
869
|
+
Args:
|
|
870
|
+
tool_name: Name of the tool
|
|
871
|
+
|
|
872
|
+
Returns:
|
|
873
|
+
Dictionary of default settings, empty dict if tool not found
|
|
874
|
+
"""
|
|
875
|
+
spec = self._tool_specs.get(tool_name)
|
|
876
|
+
if spec:
|
|
877
|
+
return deepcopy(spec.defaults)
|
|
878
|
+
return {}
|
|
879
|
+
|
|
880
|
+
def get_tool_spec(self, tool_name: str) -> Optional[ToolDefaultsSpec]:
|
|
881
|
+
"""
|
|
882
|
+
Get the full specification for a tool.
|
|
883
|
+
|
|
884
|
+
Args:
|
|
885
|
+
tool_name: Name of the tool
|
|
886
|
+
|
|
887
|
+
Returns:
|
|
888
|
+
ToolDefaultsSpec or None if not found
|
|
889
|
+
"""
|
|
890
|
+
return self._tool_specs.get(tool_name)
|
|
891
|
+
|
|
892
|
+
def get_all_tool_defaults(self) -> Dict[str, Dict[str, Any]]:
|
|
893
|
+
"""
|
|
894
|
+
Get all tool default settings.
|
|
895
|
+
|
|
896
|
+
Returns:
|
|
897
|
+
Dictionary mapping tool names to their default settings
|
|
898
|
+
"""
|
|
899
|
+
return {
|
|
900
|
+
name: deepcopy(spec.defaults)
|
|
901
|
+
for name, spec in self._tool_specs.items()
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
def get_all_defaults(self, tab_count: int = 7) -> Dict[str, Any]:
|
|
905
|
+
"""
|
|
906
|
+
Get complete default settings including app-level and all tool defaults.
|
|
907
|
+
|
|
908
|
+
Args:
|
|
909
|
+
tab_count: Number of tabs for input/output (default 7)
|
|
910
|
+
|
|
911
|
+
Returns:
|
|
912
|
+
Complete default settings dictionary
|
|
913
|
+
"""
|
|
914
|
+
defaults = deepcopy(self._app_defaults)
|
|
915
|
+
defaults["input_tabs"] = [""] * tab_count
|
|
916
|
+
defaults["output_tabs"] = [""] * tab_count
|
|
917
|
+
defaults["tool_settings"] = self.get_all_tool_defaults()
|
|
918
|
+
return defaults
|
|
919
|
+
|
|
920
|
+
def get_registered_tools(self) -> List[str]:
|
|
921
|
+
"""
|
|
922
|
+
Get list of all registered tool names.
|
|
923
|
+
|
|
924
|
+
Returns:
|
|
925
|
+
List of tool names
|
|
926
|
+
"""
|
|
927
|
+
return list(self._tool_specs.keys())
|
|
928
|
+
|
|
929
|
+
def validate_settings(self, settings: Dict[str, Any]) -> Tuple[bool, List[str]]:
|
|
930
|
+
"""
|
|
931
|
+
Validate settings against registered schemas.
|
|
932
|
+
|
|
933
|
+
Args:
|
|
934
|
+
settings: Settings dictionary to validate
|
|
935
|
+
|
|
936
|
+
Returns:
|
|
937
|
+
Tuple of (is_valid, list of error messages)
|
|
938
|
+
"""
|
|
939
|
+
errors = []
|
|
940
|
+
|
|
941
|
+
# Check for required app-level keys
|
|
942
|
+
required_app_keys = {"export_path", "debug_level", "selected_tool"}
|
|
943
|
+
for key in required_app_keys:
|
|
944
|
+
if key not in settings:
|
|
945
|
+
errors.append(f"Missing required app setting: {key}")
|
|
946
|
+
|
|
947
|
+
# Validate tool settings
|
|
948
|
+
tool_settings = settings.get("tool_settings", {})
|
|
949
|
+
|
|
950
|
+
for tool_name, spec in self._tool_specs.items():
|
|
951
|
+
if tool_name not in tool_settings:
|
|
952
|
+
# Tool settings missing entirely - not necessarily an error
|
|
953
|
+
# as they will be populated from defaults
|
|
954
|
+
continue
|
|
955
|
+
|
|
956
|
+
tool_config = tool_settings[tool_name]
|
|
957
|
+
|
|
958
|
+
# Check required keys for this tool
|
|
959
|
+
for required_key in spec.required_keys:
|
|
960
|
+
if required_key not in tool_config:
|
|
961
|
+
errors.append(f"Tool '{tool_name}' missing required key: {required_key}")
|
|
962
|
+
|
|
963
|
+
return (len(errors) == 0, errors)
|
|
964
|
+
|
|
965
|
+
def validate_tool_settings(self, tool_name: str, settings: Dict[str, Any]) -> Tuple[bool, List[str]]:
|
|
966
|
+
"""
|
|
967
|
+
Validate settings for a specific tool.
|
|
968
|
+
|
|
969
|
+
Args:
|
|
970
|
+
tool_name: Name of the tool
|
|
971
|
+
settings: Tool settings to validate
|
|
972
|
+
|
|
973
|
+
Returns:
|
|
974
|
+
Tuple of (is_valid, list of error messages)
|
|
975
|
+
"""
|
|
976
|
+
errors = []
|
|
977
|
+
spec = self._tool_specs.get(tool_name)
|
|
978
|
+
|
|
979
|
+
if not spec:
|
|
980
|
+
return (True, []) # Unknown tool, no validation
|
|
981
|
+
|
|
982
|
+
for required_key in spec.required_keys:
|
|
983
|
+
if required_key not in settings:
|
|
984
|
+
errors.append(f"Missing required key: {required_key}")
|
|
985
|
+
|
|
986
|
+
return (len(errors) == 0, errors)
|
|
987
|
+
|
|
988
|
+
def deep_merge(self, base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
|
|
989
|
+
"""
|
|
990
|
+
Deep merge two dictionaries, with override taking precedence.
|
|
991
|
+
|
|
992
|
+
Args:
|
|
993
|
+
base: Base dictionary (defaults)
|
|
994
|
+
override: Override dictionary (user settings)
|
|
995
|
+
|
|
996
|
+
Returns:
|
|
997
|
+
Merged dictionary
|
|
998
|
+
"""
|
|
999
|
+
result = deepcopy(base)
|
|
1000
|
+
|
|
1001
|
+
for key, value in override.items():
|
|
1002
|
+
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
|
1003
|
+
result[key] = self.deep_merge(result[key], value)
|
|
1004
|
+
else:
|
|
1005
|
+
result[key] = deepcopy(value)
|
|
1006
|
+
|
|
1007
|
+
return result
|
|
1008
|
+
|
|
1009
|
+
def merge_with_defaults(self, user_settings: Dict[str, Any], tab_count: int = 7) -> Dict[str, Any]:
|
|
1010
|
+
"""
|
|
1011
|
+
Merge user settings with defaults, filling in any missing values.
|
|
1012
|
+
|
|
1013
|
+
Args:
|
|
1014
|
+
user_settings: User's current settings
|
|
1015
|
+
tab_count: Number of tabs for input/output
|
|
1016
|
+
|
|
1017
|
+
Returns:
|
|
1018
|
+
Complete settings with defaults filled in
|
|
1019
|
+
"""
|
|
1020
|
+
defaults = self.get_all_defaults(tab_count)
|
|
1021
|
+
merged = self.deep_merge(defaults, user_settings)
|
|
1022
|
+
|
|
1023
|
+
# Ensure tool_settings has all registered tools
|
|
1024
|
+
if "tool_settings" not in merged:
|
|
1025
|
+
merged["tool_settings"] = {}
|
|
1026
|
+
|
|
1027
|
+
for tool_name in self._tool_specs:
|
|
1028
|
+
if tool_name not in merged["tool_settings"]:
|
|
1029
|
+
merged["tool_settings"][tool_name] = self.get_tool_defaults(tool_name)
|
|
1030
|
+
else:
|
|
1031
|
+
# Merge tool-specific settings with defaults
|
|
1032
|
+
tool_defaults = self.get_tool_defaults(tool_name)
|
|
1033
|
+
merged["tool_settings"][tool_name] = self.deep_merge(
|
|
1034
|
+
tool_defaults,
|
|
1035
|
+
merged["tool_settings"][tool_name]
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
return merged
|
|
1039
|
+
|
|
1040
|
+
def get_missing_settings(self, settings: Dict[str, Any]) -> Dict[str, Any]:
|
|
1041
|
+
"""
|
|
1042
|
+
Get settings that are missing from the provided settings.
|
|
1043
|
+
|
|
1044
|
+
Args:
|
|
1045
|
+
settings: Current settings to check
|
|
1046
|
+
|
|
1047
|
+
Returns:
|
|
1048
|
+
Dictionary of missing settings with their default values
|
|
1049
|
+
"""
|
|
1050
|
+
defaults = self.get_all_defaults()
|
|
1051
|
+
missing = {}
|
|
1052
|
+
|
|
1053
|
+
def find_missing(default_dict: Dict, current_dict: Dict, path: str = "") -> None:
|
|
1054
|
+
for key, value in default_dict.items():
|
|
1055
|
+
current_path = f"{path}.{key}" if path else key
|
|
1056
|
+
|
|
1057
|
+
if key not in current_dict:
|
|
1058
|
+
missing[current_path] = value
|
|
1059
|
+
elif isinstance(value, dict) and isinstance(current_dict.get(key), dict):
|
|
1060
|
+
find_missing(value, current_dict[key], current_path)
|
|
1061
|
+
|
|
1062
|
+
find_missing(defaults, settings)
|
|
1063
|
+
return missing
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
# Singleton instance for easy access
|
|
1067
|
+
_registry: Optional[SettingsDefaultsRegistry] = None
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
def get_registry() -> SettingsDefaultsRegistry:
|
|
1071
|
+
"""
|
|
1072
|
+
Get the singleton settings defaults registry instance.
|
|
1073
|
+
|
|
1074
|
+
Returns:
|
|
1075
|
+
SettingsDefaultsRegistry instance
|
|
1076
|
+
"""
|
|
1077
|
+
global _registry
|
|
1078
|
+
if _registry is None:
|
|
1079
|
+
_registry = SettingsDefaultsRegistry()
|
|
1080
|
+
return _registry
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
def reset_registry() -> None:
|
|
1084
|
+
"""Reset the registry singleton (mainly for testing)."""
|
|
1085
|
+
global _registry
|
|
1086
|
+
_registry = None
|
|
1087
|
+
SettingsDefaultsRegistry._instance = None
|