kollabor 0.4.9__py3-none-any.whl
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.
- core/__init__.py +18 -0
- core/application.py +578 -0
- core/cli.py +193 -0
- core/commands/__init__.py +43 -0
- core/commands/executor.py +277 -0
- core/commands/menu_renderer.py +319 -0
- core/commands/parser.py +186 -0
- core/commands/registry.py +331 -0
- core/commands/system_commands.py +479 -0
- core/config/__init__.py +7 -0
- core/config/llm_task_config.py +110 -0
- core/config/loader.py +501 -0
- core/config/manager.py +112 -0
- core/config/plugin_config_manager.py +346 -0
- core/config/plugin_schema.py +424 -0
- core/config/service.py +399 -0
- core/effects/__init__.py +1 -0
- core/events/__init__.py +12 -0
- core/events/bus.py +129 -0
- core/events/executor.py +154 -0
- core/events/models.py +258 -0
- core/events/processor.py +176 -0
- core/events/registry.py +289 -0
- core/fullscreen/__init__.py +19 -0
- core/fullscreen/command_integration.py +290 -0
- core/fullscreen/components/__init__.py +12 -0
- core/fullscreen/components/animation.py +258 -0
- core/fullscreen/components/drawing.py +160 -0
- core/fullscreen/components/matrix_components.py +177 -0
- core/fullscreen/manager.py +302 -0
- core/fullscreen/plugin.py +204 -0
- core/fullscreen/renderer.py +282 -0
- core/fullscreen/session.py +324 -0
- core/io/__init__.py +52 -0
- core/io/buffer_manager.py +362 -0
- core/io/config_status_view.py +272 -0
- core/io/core_status_views.py +410 -0
- core/io/input_errors.py +313 -0
- core/io/input_handler.py +2655 -0
- core/io/input_mode_manager.py +402 -0
- core/io/key_parser.py +344 -0
- core/io/layout.py +587 -0
- core/io/message_coordinator.py +204 -0
- core/io/message_renderer.py +601 -0
- core/io/modal_interaction_handler.py +315 -0
- core/io/raw_input_processor.py +946 -0
- core/io/status_renderer.py +845 -0
- core/io/terminal_renderer.py +586 -0
- core/io/terminal_state.py +551 -0
- core/io/visual_effects.py +734 -0
- core/llm/__init__.py +26 -0
- core/llm/api_communication_service.py +863 -0
- core/llm/conversation_logger.py +473 -0
- core/llm/conversation_manager.py +414 -0
- core/llm/file_operations_executor.py +1401 -0
- core/llm/hook_system.py +402 -0
- core/llm/llm_service.py +1629 -0
- core/llm/mcp_integration.py +386 -0
- core/llm/message_display_service.py +450 -0
- core/llm/model_router.py +214 -0
- core/llm/plugin_sdk.py +396 -0
- core/llm/response_parser.py +848 -0
- core/llm/response_processor.py +364 -0
- core/llm/tool_executor.py +520 -0
- core/logging/__init__.py +19 -0
- core/logging/setup.py +208 -0
- core/models/__init__.py +5 -0
- core/models/base.py +23 -0
- core/plugins/__init__.py +13 -0
- core/plugins/collector.py +212 -0
- core/plugins/discovery.py +386 -0
- core/plugins/factory.py +263 -0
- core/plugins/registry.py +152 -0
- core/storage/__init__.py +5 -0
- core/storage/state_manager.py +84 -0
- core/ui/__init__.py +6 -0
- core/ui/config_merger.py +176 -0
- core/ui/config_widgets.py +369 -0
- core/ui/live_modal_renderer.py +276 -0
- core/ui/modal_actions.py +162 -0
- core/ui/modal_overlay_renderer.py +373 -0
- core/ui/modal_renderer.py +591 -0
- core/ui/modal_state_manager.py +443 -0
- core/ui/widget_integration.py +222 -0
- core/ui/widgets/__init__.py +27 -0
- core/ui/widgets/base_widget.py +136 -0
- core/ui/widgets/checkbox.py +85 -0
- core/ui/widgets/dropdown.py +140 -0
- core/ui/widgets/label.py +78 -0
- core/ui/widgets/slider.py +185 -0
- core/ui/widgets/text_input.py +224 -0
- core/utils/__init__.py +11 -0
- core/utils/config_utils.py +656 -0
- core/utils/dict_utils.py +212 -0
- core/utils/error_utils.py +275 -0
- core/utils/key_reader.py +171 -0
- core/utils/plugin_utils.py +267 -0
- core/utils/prompt_renderer.py +151 -0
- kollabor-0.4.9.dist-info/METADATA +298 -0
- kollabor-0.4.9.dist-info/RECORD +128 -0
- kollabor-0.4.9.dist-info/WHEEL +5 -0
- kollabor-0.4.9.dist-info/entry_points.txt +2 -0
- kollabor-0.4.9.dist-info/licenses/LICENSE +21 -0
- kollabor-0.4.9.dist-info/top_level.txt +4 -0
- kollabor_cli_main.py +20 -0
- plugins/__init__.py +1 -0
- plugins/enhanced_input/__init__.py +18 -0
- plugins/enhanced_input/box_renderer.py +103 -0
- plugins/enhanced_input/box_styles.py +142 -0
- plugins/enhanced_input/color_engine.py +165 -0
- plugins/enhanced_input/config.py +150 -0
- plugins/enhanced_input/cursor_manager.py +72 -0
- plugins/enhanced_input/geometry.py +81 -0
- plugins/enhanced_input/state.py +130 -0
- plugins/enhanced_input/text_processor.py +115 -0
- plugins/enhanced_input_plugin.py +385 -0
- plugins/fullscreen/__init__.py +9 -0
- plugins/fullscreen/example_plugin.py +327 -0
- plugins/fullscreen/matrix_plugin.py +132 -0
- plugins/hook_monitoring_plugin.py +1299 -0
- plugins/query_enhancer_plugin.py +350 -0
- plugins/save_conversation_plugin.py +502 -0
- plugins/system_commands_plugin.py +93 -0
- plugins/tmux_plugin.py +795 -0
- plugins/workflow_enforcement_plugin.py +629 -0
- system_prompt/default.md +1286 -0
- system_prompt/default_win.md +265 -0
- system_prompt/example_with_trender.md +47 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
"""Core system commands for Kollabor CLI."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Dict, Any, List
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from ..events.models import (
|
|
8
|
+
CommandDefinition,
|
|
9
|
+
CommandMode,
|
|
10
|
+
CommandCategory,
|
|
11
|
+
CommandResult,
|
|
12
|
+
SlashCommand,
|
|
13
|
+
UIConfig
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SystemCommandsPlugin:
|
|
20
|
+
"""Core system commands plugin.
|
|
21
|
+
|
|
22
|
+
Provides essential system management commands like /help, /config, /status.
|
|
23
|
+
These commands are automatically registered at application startup.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, command_registry, event_bus, config_manager) -> None:
|
|
27
|
+
"""Initialize system commands plugin.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
command_registry: Command registry for registration.
|
|
31
|
+
event_bus: Event bus for system events.
|
|
32
|
+
config_manager: Configuration manager for system settings.
|
|
33
|
+
"""
|
|
34
|
+
self.name = "system"
|
|
35
|
+
self.command_registry = command_registry
|
|
36
|
+
self.event_bus = event_bus
|
|
37
|
+
self.config_manager = config_manager
|
|
38
|
+
self.logger = logger
|
|
39
|
+
|
|
40
|
+
def register_commands(self) -> None:
|
|
41
|
+
"""Register all system commands."""
|
|
42
|
+
try:
|
|
43
|
+
# Register /help command
|
|
44
|
+
help_command = CommandDefinition(
|
|
45
|
+
name="help",
|
|
46
|
+
description="Show available commands and usage",
|
|
47
|
+
handler=self.handle_help,
|
|
48
|
+
plugin_name=self.name,
|
|
49
|
+
category=CommandCategory.SYSTEM,
|
|
50
|
+
mode=CommandMode.INSTANT,
|
|
51
|
+
aliases=["h", "?"],
|
|
52
|
+
icon="❓"
|
|
53
|
+
)
|
|
54
|
+
self.command_registry.register_command(help_command)
|
|
55
|
+
|
|
56
|
+
# Register /config command
|
|
57
|
+
config_command = CommandDefinition(
|
|
58
|
+
name="config",
|
|
59
|
+
description="Open system configuration panel",
|
|
60
|
+
handler=self.handle_config,
|
|
61
|
+
plugin_name=self.name,
|
|
62
|
+
category=CommandCategory.SYSTEM,
|
|
63
|
+
mode=CommandMode.STATUS_TAKEOVER,
|
|
64
|
+
aliases=["settings", "preferences"],
|
|
65
|
+
icon="[INFO]",
|
|
66
|
+
ui_config=UIConfig(
|
|
67
|
+
type="tree",
|
|
68
|
+
navigation=["↑↓←→", "Enter", "Esc"],
|
|
69
|
+
height=15,
|
|
70
|
+
title="System Configuration",
|
|
71
|
+
footer="↑↓←→ navigate • Enter edit • Esc exit"
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
self.command_registry.register_command(config_command)
|
|
75
|
+
|
|
76
|
+
# Register /status command
|
|
77
|
+
status_command = CommandDefinition(
|
|
78
|
+
name="status",
|
|
79
|
+
description="Show system status and diagnostics",
|
|
80
|
+
handler=self.handle_status,
|
|
81
|
+
plugin_name=self.name,
|
|
82
|
+
category=CommandCategory.SYSTEM,
|
|
83
|
+
mode=CommandMode.STATUS_TAKEOVER,
|
|
84
|
+
aliases=["info", "diagnostics"],
|
|
85
|
+
icon="[STATS]",
|
|
86
|
+
ui_config=UIConfig(
|
|
87
|
+
type="table",
|
|
88
|
+
navigation=["↑↓", "Esc"],
|
|
89
|
+
height=12,
|
|
90
|
+
title="System Status",
|
|
91
|
+
footer="↑↓ navigate • Esc exit"
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
self.command_registry.register_command(status_command)
|
|
95
|
+
|
|
96
|
+
# Register /version command
|
|
97
|
+
version_command = CommandDefinition(
|
|
98
|
+
name="version",
|
|
99
|
+
description="Show application version information",
|
|
100
|
+
handler=self.handle_version,
|
|
101
|
+
plugin_name=self.name,
|
|
102
|
+
category=CommandCategory.SYSTEM,
|
|
103
|
+
mode=CommandMode.INSTANT,
|
|
104
|
+
aliases=["v", "ver"],
|
|
105
|
+
icon="[INFO]"
|
|
106
|
+
)
|
|
107
|
+
self.command_registry.register_command(version_command)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
self.logger.info("System commands registered successfully")
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
self.logger.error(f"Error registering system commands: {e}")
|
|
115
|
+
|
|
116
|
+
async def handle_help(self, command: SlashCommand) -> CommandResult:
|
|
117
|
+
"""Handle /help command.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
command: Parsed slash command.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Command execution result.
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
if command.args:
|
|
127
|
+
# Show help for specific command
|
|
128
|
+
command_name = command.args[0]
|
|
129
|
+
return await self._show_command_help(command_name)
|
|
130
|
+
else:
|
|
131
|
+
# Show all commands categorized by plugin
|
|
132
|
+
return await self._show_all_commands()
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
self.logger.error(f"Error in help command: {e}")
|
|
136
|
+
return CommandResult(
|
|
137
|
+
success=False,
|
|
138
|
+
message=f"Error displaying help: {str(e)}",
|
|
139
|
+
display_type="error"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
async def handle_config(self, command: SlashCommand) -> CommandResult:
|
|
143
|
+
"""Handle /config command.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
command: Parsed slash command.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Command execution result with status UI.
|
|
150
|
+
"""
|
|
151
|
+
try:
|
|
152
|
+
# Import the comprehensive config widget definitions
|
|
153
|
+
from ..ui.config_widgets import ConfigWidgetDefinitions
|
|
154
|
+
|
|
155
|
+
# Get the complete configuration modal definition
|
|
156
|
+
modal_definition = ConfigWidgetDefinitions.get_config_modal_definition()
|
|
157
|
+
|
|
158
|
+
return CommandResult(
|
|
159
|
+
success=True,
|
|
160
|
+
message="Configuration modal opened",
|
|
161
|
+
ui_config=UIConfig(
|
|
162
|
+
type="modal",
|
|
163
|
+
title=modal_definition["title"],
|
|
164
|
+
width=modal_definition["width"],
|
|
165
|
+
modal_config=modal_definition
|
|
166
|
+
),
|
|
167
|
+
display_type="modal"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
except Exception as e:
|
|
171
|
+
self.logger.error(f"Error in config command: {e}")
|
|
172
|
+
return CommandResult(
|
|
173
|
+
success=False,
|
|
174
|
+
message=f"Error opening configuration: {str(e)}",
|
|
175
|
+
display_type="error"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
async def handle_status(self, command: SlashCommand) -> CommandResult:
|
|
179
|
+
"""Handle /status command.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
command: Parsed slash command.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Command execution result with status modal UI.
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
# Create status modal definition (similar to config modal)
|
|
189
|
+
status_definition = self._get_status_modal_definition()
|
|
190
|
+
|
|
191
|
+
return CommandResult(
|
|
192
|
+
success=True,
|
|
193
|
+
message="System status opened",
|
|
194
|
+
ui_config=UIConfig(
|
|
195
|
+
type="modal",
|
|
196
|
+
title=status_definition["title"],
|
|
197
|
+
width=status_definition.get("width", 70),
|
|
198
|
+
modal_config=status_definition
|
|
199
|
+
),
|
|
200
|
+
display_type="modal"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
except Exception as e:
|
|
204
|
+
self.logger.error(f"Error in status command: {e}")
|
|
205
|
+
return CommandResult(
|
|
206
|
+
success=False,
|
|
207
|
+
message=f"Error showing status: {str(e)}",
|
|
208
|
+
display_type="error"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
def _get_status_modal_definition(self) -> Dict[str, Any]:
|
|
212
|
+
"""Get status modal definition with live system data.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Modal definition dictionary for status display.
|
|
216
|
+
"""
|
|
217
|
+
import platform
|
|
218
|
+
import sys
|
|
219
|
+
import os
|
|
220
|
+
|
|
221
|
+
stats = self.command_registry.get_registry_stats()
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
"title": "System Status",
|
|
225
|
+
"footer": "Esc to close",
|
|
226
|
+
"width": 70,
|
|
227
|
+
"height": 18,
|
|
228
|
+
"sections": [
|
|
229
|
+
{
|
|
230
|
+
"title": "Commands",
|
|
231
|
+
"widgets": [
|
|
232
|
+
{"type": "label", "label": "Registered", "value": str(stats.get('total_commands', 0))},
|
|
233
|
+
{"type": "label", "label": "Enabled", "value": str(stats.get('enabled_commands', 0))},
|
|
234
|
+
{"type": "label", "label": "Categories", "value": str(stats.get('categories', 0))},
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"title": "Plugins",
|
|
239
|
+
"widgets": [
|
|
240
|
+
{"type": "label", "label": "Active", "value": str(stats.get('plugins', 0))},
|
|
241
|
+
]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"title": "System",
|
|
245
|
+
"widgets": [
|
|
246
|
+
{"type": "label", "label": "Python", "value": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"},
|
|
247
|
+
{"type": "label", "label": "Platform", "value": platform.system()},
|
|
248
|
+
{"type": "label", "label": "Architecture", "value": platform.machine()},
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"title": "Services",
|
|
253
|
+
"widgets": [
|
|
254
|
+
{"type": "label", "label": "Event Bus", "value": "[OK] Active"},
|
|
255
|
+
{"type": "label", "label": "Input Handler", "value": "[OK] Running"},
|
|
256
|
+
{"type": "label", "label": "Terminal Renderer", "value": "[OK] Active"},
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
"actions": [
|
|
261
|
+
{"key": "Escape", "label": "Close", "action": "cancel", "style": "secondary"}
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async def handle_version(self, command: SlashCommand) -> CommandResult:
|
|
266
|
+
"""Handle /version command.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
command: Parsed slash command.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Command execution result.
|
|
273
|
+
"""
|
|
274
|
+
try:
|
|
275
|
+
# Get version information
|
|
276
|
+
version_info = self._get_version_info()
|
|
277
|
+
|
|
278
|
+
message = f"""Kollabor CLI v{version_info['version']}
|
|
279
|
+
Built: {version_info['build_date']}
|
|
280
|
+
Python: {version_info['python_version']}
|
|
281
|
+
Platform: {version_info['platform']}"""
|
|
282
|
+
|
|
283
|
+
return CommandResult(
|
|
284
|
+
success=True,
|
|
285
|
+
message=message,
|
|
286
|
+
display_type="info",
|
|
287
|
+
data=version_info
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
except Exception as e:
|
|
291
|
+
self.logger.error(f"Error in version command: {e}")
|
|
292
|
+
return CommandResult(
|
|
293
|
+
success=False,
|
|
294
|
+
message=f"Error getting version: {str(e)}",
|
|
295
|
+
display_type="error"
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
async def _show_command_help(self, command_name: str) -> CommandResult:
|
|
301
|
+
"""Show help for a specific command.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
command_name: Name of command to show help for.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
Command result with help information.
|
|
308
|
+
"""
|
|
309
|
+
command_def = self.command_registry.get_command(command_name)
|
|
310
|
+
if not command_def:
|
|
311
|
+
return CommandResult(
|
|
312
|
+
success=False,
|
|
313
|
+
message=f"Unknown command: /{command_name}",
|
|
314
|
+
display_type="error"
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# Format detailed help for the command
|
|
318
|
+
help_text = f"""Command: /{command_def.name}
|
|
319
|
+
Description: {command_def.description}
|
|
320
|
+
Plugin: {command_def.plugin_name}
|
|
321
|
+
Category: {command_def.category.value}
|
|
322
|
+
Mode: {command_def.mode.value}"""
|
|
323
|
+
|
|
324
|
+
if command_def.aliases:
|
|
325
|
+
help_text += f"\nAliases: {', '.join(command_def.aliases)}"
|
|
326
|
+
|
|
327
|
+
if command_def.parameters:
|
|
328
|
+
help_text += "\nParameters:"
|
|
329
|
+
for param in command_def.parameters:
|
|
330
|
+
required = " (required)" if param.required else ""
|
|
331
|
+
help_text += f"\n {param.name}: {param.description}{required}"
|
|
332
|
+
|
|
333
|
+
return CommandResult(
|
|
334
|
+
success=True,
|
|
335
|
+
message=help_text,
|
|
336
|
+
display_type="info"
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
async def _show_all_commands(self) -> CommandResult:
|
|
340
|
+
"""Show all available commands grouped by plugin in a status modal.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
Command result with status modal UI config.
|
|
344
|
+
"""
|
|
345
|
+
# Get commands grouped by plugin
|
|
346
|
+
plugin_categories = self.command_registry.get_plugin_categories()
|
|
347
|
+
|
|
348
|
+
# Build command list for modal display
|
|
349
|
+
command_sections = []
|
|
350
|
+
|
|
351
|
+
for plugin_name in sorted(plugin_categories.keys()):
|
|
352
|
+
commands = self.command_registry.get_commands_by_plugin(plugin_name)
|
|
353
|
+
if not commands:
|
|
354
|
+
continue
|
|
355
|
+
|
|
356
|
+
# Create section for this plugin
|
|
357
|
+
section_commands = []
|
|
358
|
+
for cmd in sorted(commands, key=lambda c: c.name):
|
|
359
|
+
aliases = f" ({', '.join(cmd.aliases)})" if cmd.aliases else ""
|
|
360
|
+
section_commands.append({
|
|
361
|
+
"name": f"/{cmd.name}{aliases}",
|
|
362
|
+
"description": cmd.description
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
command_sections.append({
|
|
366
|
+
"title": f"{plugin_name.title()} Commands",
|
|
367
|
+
"commands": section_commands
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
return CommandResult(
|
|
371
|
+
success=True,
|
|
372
|
+
message="Help opened in status modal",
|
|
373
|
+
ui_config=UIConfig(
|
|
374
|
+
type="status_modal",
|
|
375
|
+
title="Available Commands",
|
|
376
|
+
height=15,
|
|
377
|
+
width=80,
|
|
378
|
+
modal_config={
|
|
379
|
+
"sections": command_sections,
|
|
380
|
+
"footer": "Press Esc to close • Use /help <command> for detailed help",
|
|
381
|
+
"scrollable": True
|
|
382
|
+
}
|
|
383
|
+
),
|
|
384
|
+
display_type="status_modal"
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
def _get_version_info(self) -> Dict[str, str]:
|
|
388
|
+
"""Get application version information.
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
Dictionary with version details.
|
|
392
|
+
"""
|
|
393
|
+
import sys
|
|
394
|
+
import platform
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
"version": "1.0.0-dev",
|
|
398
|
+
"build_date": datetime.now().strftime("%Y-%m-%d"),
|
|
399
|
+
"python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
400
|
+
"platform": platform.system(),
|
|
401
|
+
"architecture": platform.machine()
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
class SystemConfigUI:
|
|
406
|
+
"""UI component for system configuration."""
|
|
407
|
+
|
|
408
|
+
def __init__(self, config_manager, event_bus) -> None:
|
|
409
|
+
"""Initialize config UI.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
config_manager: Configuration manager.
|
|
413
|
+
event_bus: Event bus for configuration events.
|
|
414
|
+
"""
|
|
415
|
+
self.config_manager = config_manager
|
|
416
|
+
self.event_bus = event_bus
|
|
417
|
+
|
|
418
|
+
def render(self) -> List[str]:
|
|
419
|
+
"""Render configuration interface.
|
|
420
|
+
|
|
421
|
+
Returns:
|
|
422
|
+
List of lines for display.
|
|
423
|
+
"""
|
|
424
|
+
# This would be implemented to show actual config options
|
|
425
|
+
return [
|
|
426
|
+
"╭─ System Configuration ─────────────────────────────────────╮",
|
|
427
|
+
"│ │",
|
|
428
|
+
"│ ❯ Terminal Settings │",
|
|
429
|
+
"│ Input Configuration │",
|
|
430
|
+
"│ Display Options │",
|
|
431
|
+
"│ Performance Settings │",
|
|
432
|
+
"│ │",
|
|
433
|
+
"│ Plugin Settings │",
|
|
434
|
+
"│ Event Bus Configuration │",
|
|
435
|
+
"│ Logging Options │",
|
|
436
|
+
"│ │",
|
|
437
|
+
"╰─────────────────────────────────────────────────────────────╯",
|
|
438
|
+
" ↑↓←→ navigate • Enter edit • Esc exit"
|
|
439
|
+
]
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class SystemStatusUI:
|
|
443
|
+
"""UI component for system status display."""
|
|
444
|
+
|
|
445
|
+
def __init__(self, event_bus, command_registry) -> None:
|
|
446
|
+
"""Initialize status UI.
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
event_bus: Event bus for status information.
|
|
450
|
+
command_registry: Command registry for statistics.
|
|
451
|
+
"""
|
|
452
|
+
self.event_bus = event_bus
|
|
453
|
+
self.command_registry = command_registry
|
|
454
|
+
|
|
455
|
+
def render(self) -> List[str]:
|
|
456
|
+
"""Render status interface.
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
List of lines for display.
|
|
460
|
+
"""
|
|
461
|
+
stats = self.command_registry.get_registry_stats()
|
|
462
|
+
|
|
463
|
+
return [
|
|
464
|
+
"╭─ System Status ─────────────────────────────────────────────╮",
|
|
465
|
+
"│ │",
|
|
466
|
+
f"│ Commands: {stats['total_commands']} registered, {stats['enabled_commands']} enabled │",
|
|
467
|
+
f"│ Plugins: {stats['plugins']} active │",
|
|
468
|
+
f"│ Categories: {stats['categories']} in use │",
|
|
469
|
+
"│ │",
|
|
470
|
+
"│ Event Bus: [OK] Active │",
|
|
471
|
+
"│ Input Handler: [OK] Running │",
|
|
472
|
+
"│ Terminal Renderer: [OK] Active │",
|
|
473
|
+
"│ │",
|
|
474
|
+
"│ Memory Usage: ~ 45MB │",
|
|
475
|
+
"│ Uptime: 00:15:32 │",
|
|
476
|
+
"│ │",
|
|
477
|
+
"╰─────────────────────────────────────────────────────────────╯",
|
|
478
|
+
" ↑↓ navigate • Esc exit"
|
|
479
|
+
]
|
core/config/__init__.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""LLM Service Task Management Configuration.
|
|
2
|
+
|
|
3
|
+
Configuration settings for background task management in the LLM service.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class BackgroundTasksConfig:
|
|
12
|
+
"""Configuration for background task management."""
|
|
13
|
+
max_concurrent: int = 10000
|
|
14
|
+
default_timeout: float = 0
|
|
15
|
+
cleanup_interval: int = 60 # seconds
|
|
16
|
+
enable_monitoring: bool = True
|
|
17
|
+
log_task_events: bool = True
|
|
18
|
+
log_task_errors: bool = True
|
|
19
|
+
enable_metrics: bool = True
|
|
20
|
+
|
|
21
|
+
# Advanced settings
|
|
22
|
+
task_retry_attempts: int = 0
|
|
23
|
+
task_retry_delay: float = 1.0
|
|
24
|
+
enable_task_circuit_breaker: bool = False
|
|
25
|
+
circuit_breaker_threshold: int = 5
|
|
26
|
+
circuit_breaker_timeout: float = 60.0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class QueueConfig:
|
|
31
|
+
"""Configuration for message queue management."""
|
|
32
|
+
max_size: int = 1000
|
|
33
|
+
overflow_strategy: str = "drop_oldest" # drop_oldest, drop_newest, block
|
|
34
|
+
block_timeout: Optional[float] = 1.0
|
|
35
|
+
enable_queue_metrics: bool = True
|
|
36
|
+
log_queue_events: bool = True
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class LLMTaskConfig:
|
|
41
|
+
"""Complete LLM service task configuration."""
|
|
42
|
+
background_tasks: BackgroundTasksConfig
|
|
43
|
+
queue: QueueConfig
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def from_dict(cls, config_dict: dict) -> 'LLMTaskConfig':
|
|
47
|
+
"""Create configuration from dictionary."""
|
|
48
|
+
# Background tasks config
|
|
49
|
+
bg_tasks_config = BackgroundTasksConfig(
|
|
50
|
+
max_concurrent=config_dict.get("background_tasks", {}).get("max_concurrent", 50),
|
|
51
|
+
default_timeout=config_dict.get("background_tasks", {}).get("default_timeout", 30.0),
|
|
52
|
+
cleanup_interval=config_dict.get("background_tasks", {}).get("cleanup_interval", 60),
|
|
53
|
+
enable_monitoring=config_dict.get("background_tasks", {}).get("enable_monitoring", True),
|
|
54
|
+
log_task_events=config_dict.get("background_tasks", {}).get("log_task_events", True),
|
|
55
|
+
log_task_errors=config_dict.get("background_tasks", {}).get("log_task_errors", True),
|
|
56
|
+
enable_metrics=config_dict.get("background_tasks", {}).get("enable_metrics", True),
|
|
57
|
+
task_retry_attempts=config_dict.get("background_tasks", {}).get("task_retry_attempts", 0),
|
|
58
|
+
task_retry_delay=config_dict.get("background_tasks", {}).get("task_retry_delay", 1.0),
|
|
59
|
+
enable_task_circuit_breaker=config_dict.get("background_tasks", {}).get("enable_task_circuit_breaker", False),
|
|
60
|
+
circuit_breaker_threshold=config_dict.get("background_tasks", {}).get("circuit_breaker_threshold", 5),
|
|
61
|
+
circuit_breaker_timeout=config_dict.get("background_tasks", {}).get("circuit_breaker_timeout", 60.0),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Queue config
|
|
65
|
+
queue_config = QueueConfig(
|
|
66
|
+
max_size=config_dict.get("queue", {}).get("max_size", 1000),
|
|
67
|
+
overflow_strategy=config_dict.get("queue", {}).get("overflow_strategy", "drop_oldest"),
|
|
68
|
+
block_timeout=config_dict.get("queue", {}).get("block_timeout", 1.0),
|
|
69
|
+
enable_queue_metrics=config_dict.get("queue", {}).get("enable_queue_metrics", True),
|
|
70
|
+
log_queue_events=config_dict.get("queue", {}).get("log_queue_events", True),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return cls(
|
|
74
|
+
background_tasks=bg_tasks_config,
|
|
75
|
+
queue=queue_config
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def default(cls) -> 'LLMTaskConfig':
|
|
80
|
+
"""Get default configuration."""
|
|
81
|
+
return cls(
|
|
82
|
+
background_tasks=BackgroundTasksConfig(),
|
|
83
|
+
queue=QueueConfig()
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Default configuration template
|
|
88
|
+
DEFAULT_TASK_CONFIG = {
|
|
89
|
+
"background_tasks": {
|
|
90
|
+
"max_concurrent": 10000,
|
|
91
|
+
"default_timeout": 0,
|
|
92
|
+
"cleanup_interval": 60,
|
|
93
|
+
"enable_monitoring": True,
|
|
94
|
+
"log_task_events": True,
|
|
95
|
+
"log_task_errors": True,
|
|
96
|
+
"enable_metrics": True,
|
|
97
|
+
"task_retry_attempts": 0,
|
|
98
|
+
"task_retry_delay": 1.0,
|
|
99
|
+
"enable_task_circuit_breaker": False,
|
|
100
|
+
"circuit_breaker_threshold": 5,
|
|
101
|
+
"circuit_breaker_timeout": 60.0
|
|
102
|
+
},
|
|
103
|
+
"queue": {
|
|
104
|
+
"max_size": 1000,
|
|
105
|
+
"overflow_strategy": "drop_oldest",
|
|
106
|
+
"block_timeout": 1.0,
|
|
107
|
+
"enable_queue_metrics": True,
|
|
108
|
+
"log_queue_events": True
|
|
109
|
+
}
|
|
110
|
+
}
|