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,350 @@
|
|
|
1
|
+
"""Query Enhancement Plugin for Kollabor CLI.
|
|
2
|
+
|
|
3
|
+
Uses a fast model to enhance user queries before sending to the main model,
|
|
4
|
+
dramatically improving response quality especially with "dumb" models.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import time
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
|
+
import aiohttp
|
|
11
|
+
|
|
12
|
+
from core.events.models import Event, EventType, Hook, HookPriority
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class QueryEnhancerPlugin:
|
|
18
|
+
"""Plugin that enhances user queries using a fast model before main processing."""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def get_default_config() -> Dict[str, Any]:
|
|
22
|
+
"""Get default configuration for the query enhancer plugin."""
|
|
23
|
+
config = {
|
|
24
|
+
"plugins": {
|
|
25
|
+
"query_enhancer": {
|
|
26
|
+
"enabled": False,
|
|
27
|
+
"show_status": True,
|
|
28
|
+
"fast_model": {
|
|
29
|
+
"api_url": "http://localhost:1234",
|
|
30
|
+
"model": "qwen3-0.6b",
|
|
31
|
+
"temperature": 0.3,
|
|
32
|
+
"timeout": 5
|
|
33
|
+
},
|
|
34
|
+
"enhancement_prompt": """You are a query enhancement specialist. Your job is to improve user queries to get better responses from AI assistants.
|
|
35
|
+
|
|
36
|
+
Take this user query and enhance it by:
|
|
37
|
+
1. Making it more specific and detailed
|
|
38
|
+
2. Adding relevant context
|
|
39
|
+
3. Clarifying any ambiguity
|
|
40
|
+
4. Keeping the original intent
|
|
41
|
+
|
|
42
|
+
Return ONLY the enhanced query, nothing else.
|
|
43
|
+
|
|
44
|
+
Original query: {query}
|
|
45
|
+
|
|
46
|
+
Enhanced query:""",
|
|
47
|
+
"max_length": 500,
|
|
48
|
+
"min_query_length": 10,
|
|
49
|
+
"skip_enhancement_keywords": ["hi", "hello", "thanks", "thank you", "ok", "okay", "yes", "no"],
|
|
50
|
+
"performance_tracking": True
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return config
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def get_startup_info(config) -> List[str]:
|
|
58
|
+
"""Get plugin startup information for display."""
|
|
59
|
+
enabled = config.get("plugins.query_enhancer.enabled", True)
|
|
60
|
+
fast_model = config.get("plugins.query_enhancer.fast_model.model", "qwen/qwen3-1.5b")
|
|
61
|
+
return [
|
|
62
|
+
f"Enabled: {enabled}",
|
|
63
|
+
f"Fast Model: {fast_model}",
|
|
64
|
+
f"Enhancement: {'On' if enabled else 'Off'}"
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def get_config_widgets() -> Dict[str, Any]:
|
|
69
|
+
"""Get configuration widgets for this plugin."""
|
|
70
|
+
return {
|
|
71
|
+
"title": "Query Enhancer Plugin",
|
|
72
|
+
"widgets": [
|
|
73
|
+
{"type": "checkbox", "label": "Show Status", "config_path": "plugins.query_enhancer.show_status", "help": "Display query enhancement status"},
|
|
74
|
+
{"type": "text_input", "label": "Fast Model API URL", "config_path": "plugins.query_enhancer.fast_model.api_url", "placeholder": "http://localhost:1234", "help": "API URL for fast enhancement model"},
|
|
75
|
+
{"type": "text_input", "label": "Fast Model", "config_path": "plugins.query_enhancer.fast_model.model", "placeholder": "qwen3-0.6b", "help": "Model name for query enhancement"},
|
|
76
|
+
{"type": "slider", "label": "Fast Model Temperature", "config_path": "plugins.query_enhancer.fast_model.temperature", "min_value": 0.0, "max_value": 1.0, "step": 0.1, "help": "Creativity level for enhancement (0.0-1.0)"},
|
|
77
|
+
{"type": "slider", "label": "Fast Model Timeout", "config_path": "plugins.query_enhancer.fast_model.timeout", "min_value": 1, "max_value": 30, "step": 1, "help": "Timeout for enhancement requests (seconds)"},
|
|
78
|
+
{"type": "slider", "label": "Max Query Length", "config_path": "plugins.query_enhancer.max_length", "min_value": 100, "max_value": 2000, "step": 50, "help": "Maximum enhanced query length"},
|
|
79
|
+
{"type": "slider", "label": "Min Query Length", "config_path": "plugins.query_enhancer.min_query_length", "min_value": 1, "max_value": 50, "step": 1, "help": "Minimum query length to enhance"},
|
|
80
|
+
{"type": "checkbox", "label": "Performance Tracking", "config_path": "plugins.query_enhancer.performance_tracking", "help": "Track enhancement performance metrics"}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
def __init__(self, name: str, state_manager, event_bus, renderer, config) -> None:
|
|
85
|
+
"""Initialize the query enhancer plugin.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
name: Plugin name.
|
|
89
|
+
state_manager: State management system.
|
|
90
|
+
event_bus: Event bus for hook registration.
|
|
91
|
+
renderer: Terminal renderer.
|
|
92
|
+
config: Configuration manager.
|
|
93
|
+
"""
|
|
94
|
+
self.name = name
|
|
95
|
+
self.state_manager = state_manager
|
|
96
|
+
self.event_bus = event_bus
|
|
97
|
+
self.renderer = renderer
|
|
98
|
+
self.config = config
|
|
99
|
+
|
|
100
|
+
# Plugin configuration
|
|
101
|
+
self.enabled = config.get("plugins.query_enhancer.enabled", True)
|
|
102
|
+
self.fast_model_config = config.get("plugins.query_enhancer.fast_model", {})
|
|
103
|
+
self.enhancement_prompt = config.get("plugins.query_enhancer.enhancement_prompt", "")
|
|
104
|
+
self.max_length = config.get("plugins.query_enhancer.max_length", 500)
|
|
105
|
+
self.min_query_length = config.get("plugins.query_enhancer.min_query_length", 10)
|
|
106
|
+
self.skip_keywords = config.get("plugins.query_enhancer.skip_enhancement_keywords", [])
|
|
107
|
+
|
|
108
|
+
# Performance tracking
|
|
109
|
+
self.stats = {
|
|
110
|
+
"total_queries": 0,
|
|
111
|
+
"enhanced_queries": 0,
|
|
112
|
+
"enhancement_failures": 0,
|
|
113
|
+
"avg_enhancement_time": 0.0,
|
|
114
|
+
"total_enhancement_time": 0.0
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# HTTP session for API calls
|
|
118
|
+
self.session: aiohttp.ClientSession = None
|
|
119
|
+
|
|
120
|
+
# Register hooks
|
|
121
|
+
self.hooks = [
|
|
122
|
+
Hook(
|
|
123
|
+
name="enhance_user_query",
|
|
124
|
+
plugin_name=self.name,
|
|
125
|
+
event_type=EventType.USER_INPUT_PRE,
|
|
126
|
+
priority=HookPriority.PREPROCESSING.value,
|
|
127
|
+
callback=self._enhance_query_hook,
|
|
128
|
+
timeout=config.get("plugins.query_enhancer.fast_model.timeout", 5)
|
|
129
|
+
)
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
logger.info(f"QueryEnhancer plugin '{name}' initialized with fast model: {self.fast_model_config.get('model', 'unknown')}")
|
|
133
|
+
|
|
134
|
+
def get_status_lines(self) -> Dict[str, List[str]]:
|
|
135
|
+
"""Get status lines for the query enhancer plugin organized by area.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Dictionary with status lines organized by area A, B, C.
|
|
139
|
+
"""
|
|
140
|
+
# Check if status display is enabled for this plugin
|
|
141
|
+
show_status = self.config.get('plugins.query_enhancer.show_status', True)
|
|
142
|
+
if not show_status or not self.enabled:
|
|
143
|
+
return {"A": [], "B": [], "C": []}
|
|
144
|
+
|
|
145
|
+
success_rate = 0.0
|
|
146
|
+
if self.stats["total_queries"] > 0:
|
|
147
|
+
success_rate = (self.stats["enhanced_queries"] / self.stats["total_queries"]) * 100
|
|
148
|
+
|
|
149
|
+
# Enhancement stats go in area B (performance-related)
|
|
150
|
+
return {
|
|
151
|
+
"A": [],
|
|
152
|
+
"B": [
|
|
153
|
+
f"Enhanced: {self.stats['enhanced_queries']}/{self.stats['total_queries']} ({success_rate:.1f}%)",
|
|
154
|
+
f"Avg Time: {self.stats['avg_enhancement_time']:.2f}s"
|
|
155
|
+
],
|
|
156
|
+
"C": []
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async def initialize(self) -> None:
|
|
160
|
+
"""Initialize the query enhancer plugin."""
|
|
161
|
+
if self.enabled:
|
|
162
|
+
# Create HTTP session for fast model API calls
|
|
163
|
+
timeout = aiohttp.ClientTimeout(total=self.fast_model_config.get("timeout", 5))
|
|
164
|
+
self.session = aiohttp.ClientSession(timeout=timeout)
|
|
165
|
+
logger.info("QueryEnhancer HTTP session initialized")
|
|
166
|
+
|
|
167
|
+
async def register_hooks(self) -> None:
|
|
168
|
+
"""Register query enhancement hooks."""
|
|
169
|
+
if self.enabled:
|
|
170
|
+
for hook in self.hooks:
|
|
171
|
+
await self.event_bus.register_hook(hook)
|
|
172
|
+
logger.info("QueryEnhancer hooks registered")
|
|
173
|
+
|
|
174
|
+
async def shutdown(self) -> None:
|
|
175
|
+
"""Shutdown the query enhancer plugin."""
|
|
176
|
+
if self.session:
|
|
177
|
+
await self.session.close()
|
|
178
|
+
logger.info("QueryEnhancer session closed")
|
|
179
|
+
|
|
180
|
+
async def _enhance_query_hook(self, data: Dict[str, Any], event: Event) -> Dict[str, Any]:
|
|
181
|
+
"""Hook to enhance user queries before main processing.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
data: Event data containing the user message.
|
|
185
|
+
event: The event object (used for hook system compatibility).
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Modified event data with enhanced query.
|
|
189
|
+
"""
|
|
190
|
+
if not self.enabled:
|
|
191
|
+
return data
|
|
192
|
+
|
|
193
|
+
original_query = data.get("message", "").strip()
|
|
194
|
+
if not original_query:
|
|
195
|
+
return data
|
|
196
|
+
|
|
197
|
+
self.stats["total_queries"] += 1
|
|
198
|
+
|
|
199
|
+
# Skip enhancement for very short queries or common phrases
|
|
200
|
+
if (len(original_query) < self.min_query_length or
|
|
201
|
+
any(keyword.lower() in original_query.lower() for keyword in self.skip_keywords)):
|
|
202
|
+
logger.debug(f"Skipping enhancement for short/common query: {original_query[:50]}")
|
|
203
|
+
return data
|
|
204
|
+
|
|
205
|
+
start_time = time.time()
|
|
206
|
+
try:
|
|
207
|
+
enhanced_query = await self._enhance_query(original_query)
|
|
208
|
+
enhancement_time = time.time() - start_time
|
|
209
|
+
|
|
210
|
+
if enhanced_query and enhanced_query.strip() != original_query.strip():
|
|
211
|
+
# Update stats
|
|
212
|
+
self.stats["enhanced_queries"] += 1
|
|
213
|
+
self.stats["total_enhancement_time"] += enhancement_time
|
|
214
|
+
self.stats["avg_enhancement_time"] = (
|
|
215
|
+
self.stats["total_enhancement_time"] / self.stats["enhanced_queries"]
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Return enhanced query in expected format
|
|
219
|
+
enhanced_data = data.copy()
|
|
220
|
+
enhanced_data["enhanced_message"] = enhanced_query.strip()
|
|
221
|
+
logger.info(f"Enhanced query ({enhancement_time:.2f}s): {original_query[:50]}... → {enhanced_query[:50]}...")
|
|
222
|
+
return enhanced_data
|
|
223
|
+
else:
|
|
224
|
+
logger.debug("Enhancement did not improve query, using original")
|
|
225
|
+
|
|
226
|
+
except Exception as e:
|
|
227
|
+
self.stats["enhancement_failures"] += 1
|
|
228
|
+
logger.warning(f"Query enhancement failed: {e}, using original query")
|
|
229
|
+
|
|
230
|
+
return data
|
|
231
|
+
|
|
232
|
+
async def _enhance_query(self, query: str) -> str:
|
|
233
|
+
"""Enhance a user query using the fast model.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
query: The original user query.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Enhanced query or original if enhancement fails.
|
|
240
|
+
"""
|
|
241
|
+
if not self.session:
|
|
242
|
+
raise Exception("HTTP session not initialized")
|
|
243
|
+
|
|
244
|
+
# Prepare the enhancement prompt
|
|
245
|
+
prompt = self.enhancement_prompt.format(query=query)
|
|
246
|
+
|
|
247
|
+
# Prepare API payload
|
|
248
|
+
payload = {
|
|
249
|
+
"model": self.fast_model_config.get("model", "qwen3-0.6b"),
|
|
250
|
+
"messages": [
|
|
251
|
+
{"role": "user", "content": prompt}
|
|
252
|
+
],
|
|
253
|
+
"temperature": self.fast_model_config.get("temperature", 0.3),
|
|
254
|
+
"max_tokens": self.max_length,
|
|
255
|
+
"stream": False
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
# Call the fast model API with timeout
|
|
259
|
+
api_url = self.fast_model_config.get("api_url", "http://localhost:1234")
|
|
260
|
+
timeout = self.fast_model_config.get("timeout", 5)
|
|
261
|
+
|
|
262
|
+
async with self.session.post(
|
|
263
|
+
f"{api_url}/v1/chat/completions",
|
|
264
|
+
json=payload,
|
|
265
|
+
timeout=aiohttp.ClientTimeout(total=timeout)
|
|
266
|
+
) as response:
|
|
267
|
+
if response.status != 200:
|
|
268
|
+
raise Exception(f"API returned status {response.status}")
|
|
269
|
+
|
|
270
|
+
result = await response.json()
|
|
271
|
+
raw_response = result["choices"][0]["message"]["content"].strip()
|
|
272
|
+
|
|
273
|
+
# Clean up response by removing thinking tags and extracting clean content
|
|
274
|
+
enhanced_query = self._clean_response(raw_response)
|
|
275
|
+
|
|
276
|
+
# Basic validation of enhanced query
|
|
277
|
+
if len(enhanced_query) > self.max_length * 2: # Too long
|
|
278
|
+
raise Exception("Enhanced query too long")
|
|
279
|
+
|
|
280
|
+
if not enhanced_query or enhanced_query.lower() in ["none", "n/a", "null"]:
|
|
281
|
+
raise Exception("Invalid enhanced query")
|
|
282
|
+
|
|
283
|
+
return enhanced_query
|
|
284
|
+
|
|
285
|
+
def _clean_response(self, raw_response: str) -> str:
|
|
286
|
+
"""Clean up model response by removing thinking tags and extracting enhanced query.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
raw_response: Raw response from the fast model.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Cleaned enhanced query.
|
|
293
|
+
"""
|
|
294
|
+
import re
|
|
295
|
+
|
|
296
|
+
# Remove thinking tags and their content
|
|
297
|
+
cleaned = re.sub(r'<think>.*?</think>', '', raw_response, flags=re.DOTALL)
|
|
298
|
+
cleaned = re.sub(r'<thinking>.*?</thinking>', '', cleaned, flags=re.DOTALL)
|
|
299
|
+
|
|
300
|
+
# If response still starts with <think> (unclosed tag), extract everything after it
|
|
301
|
+
if cleaned.startswith('<think>'):
|
|
302
|
+
# Find the end of the thinking section and extract what comes after
|
|
303
|
+
lines = cleaned.split('\n')
|
|
304
|
+
enhanced_lines = []
|
|
305
|
+
in_thinking = True
|
|
306
|
+
|
|
307
|
+
for line in lines:
|
|
308
|
+
line = line.strip()
|
|
309
|
+
if not line:
|
|
310
|
+
continue
|
|
311
|
+
|
|
312
|
+
# Skip obvious thinking indicators
|
|
313
|
+
if (line.startswith('<think>') or
|
|
314
|
+
line.startswith('Okay,') or
|
|
315
|
+
line.startswith('Let me') or
|
|
316
|
+
line.startswith('First,') or
|
|
317
|
+
line.startswith('I should') or
|
|
318
|
+
line.startswith('Maybe') or
|
|
319
|
+
line.startswith('The user')):
|
|
320
|
+
continue
|
|
321
|
+
|
|
322
|
+
# Look for the actual enhanced query
|
|
323
|
+
if (not in_thinking or
|
|
324
|
+
line.startswith('Enhanced query:') or
|
|
325
|
+
line.startswith('Improved query:') or
|
|
326
|
+
(len(line) > 20 and '?' in line)): # Likely a question
|
|
327
|
+
in_thinking = False
|
|
328
|
+
if line.startswith(('Enhanced query:', 'Improved query:')):
|
|
329
|
+
line = line.split(':', 1)[1].strip()
|
|
330
|
+
if line:
|
|
331
|
+
enhanced_lines.append(line)
|
|
332
|
+
|
|
333
|
+
if enhanced_lines:
|
|
334
|
+
cleaned = ' '.join(enhanced_lines)
|
|
335
|
+
|
|
336
|
+
# Clean up any remaining artifacts
|
|
337
|
+
cleaned = cleaned.strip()
|
|
338
|
+
cleaned = re.sub(r'^(Enhanced query:|Improved query:|Query:)\s*', '', cleaned, flags=re.IGNORECASE)
|
|
339
|
+
cleaned = re.sub(r'\s+', ' ', cleaned) # Normalize whitespace
|
|
340
|
+
|
|
341
|
+
# If we still don't have a good result, try to extract the most query-like sentence
|
|
342
|
+
if not cleaned or len(cleaned) < 10:
|
|
343
|
+
sentences = raw_response.split('.')
|
|
344
|
+
for sentence in sentences:
|
|
345
|
+
sentence = sentence.strip()
|
|
346
|
+
if len(sentence) > 15 and ('?' in sentence or 'how' in sentence.lower()):
|
|
347
|
+
cleaned = sentence
|
|
348
|
+
break
|
|
349
|
+
|
|
350
|
+
return cleaned.strip() if cleaned else raw_response.strip()
|