stigmergy 1.0.68 → 1.0.70
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/README.en.md +306 -300
- package/README.md +469 -301
- package/package.json +97 -81
- package/scripts/publish.js +268 -0
- package/scripts/simple-publish.js +59 -0
- package/src/index.js +12 -0
- package/test/enhanced-main-alignment.test.js +298 -0
- package/test/hook-system-integration-test.js +307 -0
- package/test/natural-language-skills-test.js +320 -0
- package/test/nl-integration-test.js +179 -0
- package/test/parameter-parsing-test.js +143 -0
- package/test/real-test.js +435 -0
- package/test/system-compatibility-test.js +447 -0
- package/test/tdd-fixes-test.js +211 -0
- package/test/third-party-skills-test.js +321 -0
- package/test/tool-selection-integration-test.js +157 -0
- package/test/unit/cli-scanner.test.js +291 -0
- package/test/unit/cross-cli-executor.test.js +399 -0
- package/src/adapters/claude/__init__.py +0 -13
- package/src/adapters/claude/claude_skills_integration.py +0 -609
- package/src/adapters/claude/hook_adapter.py +0 -663
- package/src/adapters/claude/install_claude_integration.py +0 -265
- package/src/adapters/claude/skills_hook_adapter.py +0 -841
- package/src/adapters/claude/standalone_claude_adapter.py +0 -384
- package/src/adapters/cline/__init__.py +0 -20
- package/src/adapters/cline/config.py +0 -108
- package/src/adapters/cline/install_cline_integration.py +0 -617
- package/src/adapters/cline/mcp_server.py +0 -713
- package/src/adapters/cline/standalone_cline_adapter.py +0 -459
- package/src/adapters/codebuddy/__init__.py +0 -13
- package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
- package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
- package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
- package/src/adapters/codebuddy/skills_integration.py +0 -395
- package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
- package/src/adapters/codex/__init__.py +0 -11
- package/src/adapters/codex/base.py +0 -46
- package/src/adapters/codex/install_codex_integration.py +0 -311
- package/src/adapters/codex/mcp_server.py +0 -493
- package/src/adapters/codex/natural_language_parser.py +0 -82
- package/src/adapters/codex/slash_command_adapter.py +0 -326
- package/src/adapters/codex/standalone_codex_adapter.py +0 -362
- package/src/adapters/copilot/__init__.py +0 -13
- package/src/adapters/copilot/install_copilot_integration.py +0 -564
- package/src/adapters/copilot/mcp_adapter.py +0 -772
- package/src/adapters/copilot/mcp_server.py +0 -168
- package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
- package/src/adapters/gemini/__init__.py +0 -13
- package/src/adapters/gemini/extension_adapter.py +0 -690
- package/src/adapters/gemini/install_gemini_integration.py +0 -257
- package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
- package/src/adapters/iflow/__init__.py +0 -7
- package/src/adapters/iflow/hook_adapter.py +0 -1038
- package/src/adapters/iflow/hook_installer.py +0 -536
- package/src/adapters/iflow/install_iflow_integration.py +0 -271
- package/src/adapters/iflow/official_hook_adapter.py +0 -1272
- package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
- package/src/adapters/iflow/workflow_adapter.py +0 -793
- package/src/adapters/qoder/hook_installer.py +0 -732
- package/src/adapters/qoder/install_qoder_integration.py +0 -265
- package/src/adapters/qoder/notification_hook_adapter.py +0 -863
- package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
- package/src/adapters/qwen/__init__.py +0 -17
- package/src/adapters/qwencode/__init__.py +0 -13
- package/src/adapters/qwencode/inheritance_adapter.py +0 -818
- package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
- package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
- package/src/atomic_collaboration_handler.py +0 -461
- package/src/cli_collaboration_agent.py +0 -697
- package/src/collaboration/hooks.py +0 -315
- package/src/core/__init__.py +0 -21
- package/src/core/ai_environment_scanner.py +0 -331
- package/src/core/base_adapter.py +0 -220
- package/src/core/cli_hook_integration.py +0 -406
- package/src/core/cross_cli_executor.py +0 -713
- package/src/core/cross_cli_mapping.py +0 -1165
- package/src/core/cross_platform_encoding.py +0 -365
- package/src/core/cross_platform_safe_cli.py +0 -894
- package/src/core/direct_cli_executor.py +0 -805
- package/src/core/direct_cli_hook_system.py +0 -958
- package/src/core/enhanced_init_processor.py +0 -467
- package/src/core/graceful_cli_executor.py +0 -912
- package/src/core/md_enhancer.py +0 -342
- package/src/core/md_generator.py +0 -619
- package/src/core/models.py +0 -218
- package/src/core/parser.py +0 -108
- package/src/core/real_cli_hook_system.py +0 -852
- package/src/core/real_cross_cli_system.py +0 -925
- package/src/core/verified_cross_cli_system.py +0 -961
- package/src/deploy.js +0 -737
- package/src/enhanced-main.js +0 -626
- package/src/enhanced_deploy.js +0 -303
- package/src/enhanced_universal_cli_setup.py +0 -930
- package/src/kimi_wrapper.py +0 -104
- package/src/main.js +0 -1309
- package/src/shell_integration.py +0 -398
- package/src/simple-main.js +0 -315
- package/src/smart_router_creator.py +0 -323
- package/src/universal_cli_setup.py +0 -1289
- package/src/utils/__init__.py +0 -12
- package/src/utils/cli_detector.py +0 -445
- package/src/utils/file_utils.py +0 -246
|
@@ -1,818 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
QwenCode CLI Class Inheritance适配器 - 基于QwenCode官方Class Inheritance系统的原生集成
|
|
3
|
-
|
|
4
|
-
这是TDD驱动的实现,基于test_qwencode_adapter.py中的测试用例
|
|
5
|
-
完全符合项目约束条件:
|
|
6
|
-
- 使用QwenCode CLI官方Class Inheritance机制
|
|
7
|
-
- 不改变CLI启动和使用方式
|
|
8
|
-
- 不依赖包装器
|
|
9
|
-
- 完全无损扩展
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import os
|
|
13
|
-
import json
|
|
14
|
-
import logging
|
|
15
|
-
import asyncio
|
|
16
|
-
import importlib
|
|
17
|
-
import sys
|
|
18
|
-
from typing import Dict, Any, Optional, List, Type
|
|
19
|
-
from datetime import datetime
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
|
|
22
|
-
from ...core.base_adapter import BaseCrossCLIAdapter, IntentResult
|
|
23
|
-
from ...core.parser import NaturalLanguageParser
|
|
24
|
-
|
|
25
|
-
logger = logging.getLogger(__name__)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class PluginContext:
|
|
29
|
-
"""QwenCode CLI Plugin上下文模拟类"""
|
|
30
|
-
|
|
31
|
-
def __init__(self, prompt: str = "", metadata: Optional[Dict] = None):
|
|
32
|
-
self.prompt = prompt
|
|
33
|
-
self.metadata = metadata or {}
|
|
34
|
-
self.session_id = self.metadata.get('session_id', 'unknown')
|
|
35
|
-
self.user_id = self.metadata.get('user_id', 'unknown')
|
|
36
|
-
self.plugin_name = "cross-cli-adapter"
|
|
37
|
-
self.version = "1.0.0"
|
|
38
|
-
self.class_name = "CrossCLIAdapterPlugin"
|
|
39
|
-
self.timestamp = datetime.now()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class QwenCodeInheritanceAdapter(BaseCrossCLIAdapter):
|
|
43
|
-
"""
|
|
44
|
-
QwenCode CLI Class Inheritance适配器
|
|
45
|
-
|
|
46
|
-
通过QwenCode CLI官方Class Inheritance系统实现跨CLI调用功能。
|
|
47
|
-
这是完全基于原生机制的无损扩展实现。
|
|
48
|
-
|
|
49
|
-
Inheritance机制:
|
|
50
|
-
- 继承BaseQwenCodePlugin类
|
|
51
|
-
- 重写关键方法实现跨CLI功能
|
|
52
|
-
- Plugin生命周期管理
|
|
53
|
-
- 配置文件驱动
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
def __init__(self, cli_name: str = "qwencode"):
|
|
57
|
-
"""
|
|
58
|
-
初始化QwenCode Inheritance适配器
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
cli_name: CLI工具名称,默认为"qwencode"
|
|
62
|
-
"""
|
|
63
|
-
super().__init__(cli_name)
|
|
64
|
-
|
|
65
|
-
# Inheritance相关配置
|
|
66
|
-
self.config_file = os.path.expanduser("~/.config/qwencode/config.yml")
|
|
67
|
-
self.plugins_loaded = False
|
|
68
|
-
self.plugin_handlers = {
|
|
69
|
-
'on_before_execute': self.on_before_execute,
|
|
70
|
-
'on_after_execute': self.on_after_execute,
|
|
71
|
-
'on_prompt_received': self.on_prompt_received,
|
|
72
|
-
'on_code_generated': self.on_code_generated,
|
|
73
|
-
'on_error_occurred': self.on_error_occurred,
|
|
74
|
-
'on_file_created': self.on_file_created,
|
|
75
|
-
'on_before_save': self.on_before_save,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
# 统计信息
|
|
79
|
-
self.plugin_calls_count = 0
|
|
80
|
-
self.cross_cli_calls_count = 0
|
|
81
|
-
self.processed_requests: List[Dict[str, Any]] = []
|
|
82
|
-
|
|
83
|
-
# 解析器
|
|
84
|
-
self.parser = NaturalLanguageParser()
|
|
85
|
-
|
|
86
|
-
# 跨CLI适配器工厂
|
|
87
|
-
from ...core.base_adapter import get_cross_cli_adapter
|
|
88
|
-
self.get_adapter = get_cross_cli_adapter
|
|
89
|
-
|
|
90
|
-
# Inheritance系统状态
|
|
91
|
-
self.base_class = None
|
|
92
|
-
self.plugin_module = None
|
|
93
|
-
self.inheritance_setup_complete = False
|
|
94
|
-
|
|
95
|
-
async def initialize(self) -> bool:
|
|
96
|
-
"""
|
|
97
|
-
初始化适配器
|
|
98
|
-
|
|
99
|
-
Returns:
|
|
100
|
-
bool: 初始化是否成功
|
|
101
|
-
"""
|
|
102
|
-
try:
|
|
103
|
-
# 1. 检查QwenCode CLI环境
|
|
104
|
-
if not self._check_qwencode_environment():
|
|
105
|
-
logger.error("QwenCode CLI环境检查失败")
|
|
106
|
-
return False
|
|
107
|
-
|
|
108
|
-
# 2. 设置Class Inheritance系统
|
|
109
|
-
if not await self._setup_inheritance_system():
|
|
110
|
-
logger.error("Class Inheritance系统设置失败")
|
|
111
|
-
return False
|
|
112
|
-
|
|
113
|
-
# 3. 加载插件
|
|
114
|
-
if not await self._load_plugins():
|
|
115
|
-
logger.error("插件加载失败")
|
|
116
|
-
return False
|
|
117
|
-
|
|
118
|
-
# 4. 创建配置目录
|
|
119
|
-
await self._ensure_config_directory()
|
|
120
|
-
|
|
121
|
-
self.plugins_loaded = True
|
|
122
|
-
logger.info("QwenCode Class Inheritance适配器初始化成功")
|
|
123
|
-
return True
|
|
124
|
-
|
|
125
|
-
except Exception as e:
|
|
126
|
-
logger.error(f"初始化QwenCode Class Inheritance适配器失败: {e}")
|
|
127
|
-
self.record_error()
|
|
128
|
-
return False
|
|
129
|
-
|
|
130
|
-
async def _setup_inheritance_system(self) -> bool:
|
|
131
|
-
"""
|
|
132
|
-
设置Class Inheritance系统
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
bool: 设置是否成功
|
|
136
|
-
"""
|
|
137
|
-
try:
|
|
138
|
-
# 尝试导入QwenCode的基础Plugin类
|
|
139
|
-
try:
|
|
140
|
-
# 这里模拟导入QwenCode的基础类
|
|
141
|
-
# 实际实现中需要根据QwenCode的实际API调整
|
|
142
|
-
base_class_path = "qwencode.plugins.base"
|
|
143
|
-
|
|
144
|
-
# 创建模拟的基础类用于测试
|
|
145
|
-
class MockBaseQwenCodePlugin:
|
|
146
|
-
def __init__(self):
|
|
147
|
-
self.name = "BasePlugin"
|
|
148
|
-
self.version = "1.0.0"
|
|
149
|
-
self.enabled = True
|
|
150
|
-
|
|
151
|
-
def execute(self, prompt: str, **kwargs):
|
|
152
|
-
return f"Mock execution: {prompt}"
|
|
153
|
-
|
|
154
|
-
def validate_input(self, prompt: str) -> bool:
|
|
155
|
-
return bool(prompt and prompt.strip())
|
|
156
|
-
|
|
157
|
-
def format_output(self, result: str) -> str:
|
|
158
|
-
return result
|
|
159
|
-
|
|
160
|
-
self.base_class = MockBaseQwenCodePlugin
|
|
161
|
-
logger.info("QwenCode基础Plugin类导入成功")
|
|
162
|
-
|
|
163
|
-
except ImportError as e:
|
|
164
|
-
logger.warning(f"无法导入QwenCode基础类,使用模拟类: {e}")
|
|
165
|
-
# 创建模拟基础类
|
|
166
|
-
class MockBaseQwenCodePlugin:
|
|
167
|
-
def __init__(self):
|
|
168
|
-
self.name = "BasePlugin"
|
|
169
|
-
self.version = "1.0.0"
|
|
170
|
-
self.enabled = True
|
|
171
|
-
|
|
172
|
-
def execute(self, prompt: str, **kwargs):
|
|
173
|
-
return f"Mock execution: {prompt}"
|
|
174
|
-
|
|
175
|
-
def validate_input(self, prompt: str) -> bool:
|
|
176
|
-
return bool(prompt and prompt.strip())
|
|
177
|
-
|
|
178
|
-
def format_output(self, result: str) -> str:
|
|
179
|
-
return result
|
|
180
|
-
|
|
181
|
-
self.base_class = MockBaseQwenCodePlugin
|
|
182
|
-
|
|
183
|
-
# 创建插件模块
|
|
184
|
-
plugin_module_path = f"qwencode.plugins.{self.plugin_name.lower()}"
|
|
185
|
-
self.plugin_module = type('PluginModule', (), {})
|
|
186
|
-
|
|
187
|
-
self.inheritance_setup_complete = True
|
|
188
|
-
return True
|
|
189
|
-
|
|
190
|
-
except Exception as e:
|
|
191
|
-
logger.error(f"设置Class Inheritance系统失败: {e}")
|
|
192
|
-
return False
|
|
193
|
-
|
|
194
|
-
async def _load_plugins(self) -> bool:
|
|
195
|
-
"""
|
|
196
|
-
加载插件
|
|
197
|
-
|
|
198
|
-
Returns:
|
|
199
|
-
bool: 加载是否成功
|
|
200
|
-
"""
|
|
201
|
-
try:
|
|
202
|
-
# 读取现有配置
|
|
203
|
-
config = self._load_config()
|
|
204
|
-
|
|
205
|
-
# 添加我们的插件配置
|
|
206
|
-
cross_cli_plugin = {
|
|
207
|
-
"name": "CrossCLIAdapterPlugin",
|
|
208
|
-
"class": "CrossCLIAdapterPlugin",
|
|
209
|
-
"enabled": True,
|
|
210
|
-
"priority": 85,
|
|
211
|
-
"base_class": "BaseQwenCodePlugin",
|
|
212
|
-
"handlers": [
|
|
213
|
-
"on_prompt_received",
|
|
214
|
-
"on_code_generated",
|
|
215
|
-
"on_error_occurred"
|
|
216
|
-
],
|
|
217
|
-
"config": {
|
|
218
|
-
"cross_cli_enabled": True,
|
|
219
|
-
"supported_clis": ["claude", "gemini", "iflow", "qoder", "codebuddy", "codex"],
|
|
220
|
-
"auto_detect": True
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
# 检查是否已存在
|
|
225
|
-
existing_plugins = config.get('plugins', [])
|
|
226
|
-
plugin_exists = any(
|
|
227
|
-
plugin['name'] == cross_cli_plugin['name']
|
|
228
|
-
for plugin in existing_plugins
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
if not plugin_exists:
|
|
232
|
-
existing_plugins.append(cross_cli_plugin)
|
|
233
|
-
config['plugins'] = existing_plugins
|
|
234
|
-
|
|
235
|
-
# 保存配置
|
|
236
|
-
await self._save_config(config)
|
|
237
|
-
logger.info(f"加载Plugin: {cross_cli_plugin['name']}")
|
|
238
|
-
else:
|
|
239
|
-
logger.info("Plugin已存在,跳过加载")
|
|
240
|
-
|
|
241
|
-
return True
|
|
242
|
-
|
|
243
|
-
except Exception as e:
|
|
244
|
-
logger.error(f"加载Plugin失败: {e}")
|
|
245
|
-
return False
|
|
246
|
-
|
|
247
|
-
def _load_config(self) -> Dict[str, Any]:
|
|
248
|
-
"""
|
|
249
|
-
加载配置
|
|
250
|
-
|
|
251
|
-
Returns:
|
|
252
|
-
Dict[str, Any]: 配置
|
|
253
|
-
"""
|
|
254
|
-
if os.path.exists(self.config_file):
|
|
255
|
-
try:
|
|
256
|
-
import yaml
|
|
257
|
-
with open(self.config_file, 'r', encoding='utf-8') as f:
|
|
258
|
-
return yaml.safe_load(f) or {}
|
|
259
|
-
except Exception as e:
|
|
260
|
-
logger.warning(f"加载配置失败,使用默认配置: {e}")
|
|
261
|
-
|
|
262
|
-
# 返回默认配置
|
|
263
|
-
return {
|
|
264
|
-
"version": "1.0",
|
|
265
|
-
"plugins": []
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
async def _save_config(self, config: Dict[str, Any]) -> bool:
|
|
269
|
-
"""
|
|
270
|
-
保存配置
|
|
271
|
-
|
|
272
|
-
Args:
|
|
273
|
-
config: 配置
|
|
274
|
-
|
|
275
|
-
Returns:
|
|
276
|
-
bool: 保存是否成功
|
|
277
|
-
"""
|
|
278
|
-
try:
|
|
279
|
-
import yaml
|
|
280
|
-
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
|
281
|
-
|
|
282
|
-
with open(self.config_file, 'w', encoding='utf-8') as f:
|
|
283
|
-
yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
|
|
284
|
-
|
|
285
|
-
logger.info(f"保存配置到: {self.config_file}")
|
|
286
|
-
return True
|
|
287
|
-
|
|
288
|
-
except Exception as e:
|
|
289
|
-
logger.error(f"保存配置失败: {e}")
|
|
290
|
-
return False
|
|
291
|
-
|
|
292
|
-
async def _ensure_config_directory(self) -> bool:
|
|
293
|
-
"""
|
|
294
|
-
确保配置目录存在
|
|
295
|
-
|
|
296
|
-
Returns:
|
|
297
|
-
bool: 创建是否成功
|
|
298
|
-
"""
|
|
299
|
-
try:
|
|
300
|
-
config_dir = os.path.expanduser("~/.config/qwencode")
|
|
301
|
-
os.makedirs(config_dir, exist_ok=True)
|
|
302
|
-
|
|
303
|
-
# 创建适配器配置目录
|
|
304
|
-
adapter_dir = os.path.join(config_dir, "adapters")
|
|
305
|
-
os.makedirs(adapter_dir, exist_ok=True)
|
|
306
|
-
|
|
307
|
-
logger.info(f"配置目录已准备: {config_dir}")
|
|
308
|
-
return True
|
|
309
|
-
|
|
310
|
-
except Exception as e:
|
|
311
|
-
logger.error(f"创建配置目录失败: {e}")
|
|
312
|
-
return False
|
|
313
|
-
|
|
314
|
-
def _check_qwencode_environment(self) -> bool:
|
|
315
|
-
"""
|
|
316
|
-
检查QwenCode CLI环境
|
|
317
|
-
|
|
318
|
-
Returns:
|
|
319
|
-
bool: 环境是否可用
|
|
320
|
-
"""
|
|
321
|
-
# 这里应该检查QwenCode CLI是否可用
|
|
322
|
-
# 暂时返回True,实际实现中需要检查CLI命令和配置
|
|
323
|
-
return True
|
|
324
|
-
|
|
325
|
-
async def on_prompt_received(self, context: PluginContext) -> Optional[str]:
|
|
326
|
-
"""
|
|
327
|
-
接收到提示时的Plugin处理函数
|
|
328
|
-
|
|
329
|
-
这是核心Plugin,用于检测和执行跨CLI调用。
|
|
330
|
-
|
|
331
|
-
Args:
|
|
332
|
-
context: Plugin上下文
|
|
333
|
-
|
|
334
|
-
Returns:
|
|
335
|
-
Optional[str]: 处理结果,如果返回None则让QwenCode继续正常处理
|
|
336
|
-
"""
|
|
337
|
-
try:
|
|
338
|
-
self.plugin_calls_count += 1
|
|
339
|
-
user_input = context.prompt
|
|
340
|
-
|
|
341
|
-
# 记录请求
|
|
342
|
-
request_record = {
|
|
343
|
-
'plugin_type': 'on_prompt_received',
|
|
344
|
-
'prompt': user_input,
|
|
345
|
-
'metadata': context.metadata,
|
|
346
|
-
'timestamp': datetime.now().isoformat()
|
|
347
|
-
}
|
|
348
|
-
self.processed_requests.append(request_record)
|
|
349
|
-
|
|
350
|
-
# 1. 检测是否为跨CLI调用意图
|
|
351
|
-
intent = self.parser.parse_intent(user_input, "qwencode")
|
|
352
|
-
|
|
353
|
-
if not intent.is_cross_cli:
|
|
354
|
-
# 不是跨CLI调用,让QwenCode继续处理
|
|
355
|
-
return None
|
|
356
|
-
|
|
357
|
-
# 2. 避免自我调用
|
|
358
|
-
if intent.target_cli == self.cli_name:
|
|
359
|
-
# 目标是QwenCode自己,让QwenCode处理
|
|
360
|
-
return None
|
|
361
|
-
|
|
362
|
-
# 3. 执行跨CLI调用
|
|
363
|
-
result = await self._execute_cross_cli_call(
|
|
364
|
-
intent.target_cli,
|
|
365
|
-
intent.task,
|
|
366
|
-
context
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
if result:
|
|
370
|
-
self.cross_cli_calls_count += 1
|
|
371
|
-
return result
|
|
372
|
-
|
|
373
|
-
return None
|
|
374
|
-
|
|
375
|
-
except Exception as e:
|
|
376
|
-
logger.error(f"接收到提示Plugin处理失败: {e}")
|
|
377
|
-
self.record_error()
|
|
378
|
-
return None
|
|
379
|
-
|
|
380
|
-
def _parse_cross_cli_intent(self, user_input: str) -> tuple:
|
|
381
|
-
"""
|
|
382
|
-
解析跨CLI调用意图(测试兼容方法)
|
|
383
|
-
|
|
384
|
-
Args:
|
|
385
|
-
user_input: 用户输入
|
|
386
|
-
|
|
387
|
-
Returns:
|
|
388
|
-
tuple: (target_cli, task)
|
|
389
|
-
"""
|
|
390
|
-
try:
|
|
391
|
-
intent = self.parser.parse_intent(user_input, "qwencode")
|
|
392
|
-
if intent.is_cross_cli:
|
|
393
|
-
return intent.target_cli, intent.task
|
|
394
|
-
return None, None
|
|
395
|
-
except Exception:
|
|
396
|
-
return None, None
|
|
397
|
-
|
|
398
|
-
async def execute_cross_cli_call(self, target_cli: str, task: str, context: PluginContext) -> str:
|
|
399
|
-
"""
|
|
400
|
-
执行跨CLI调用(测试兼容方法)
|
|
401
|
-
|
|
402
|
-
Args:
|
|
403
|
-
target_cli: 目标CLI工具
|
|
404
|
-
task: 要执行的任务
|
|
405
|
-
context: Plugin上下文
|
|
406
|
-
|
|
407
|
-
Returns:
|
|
408
|
-
str: 执行结果
|
|
409
|
-
"""
|
|
410
|
-
result = await self._execute_cross_cli_call(target_cli, task, context)
|
|
411
|
-
if result:
|
|
412
|
-
return result
|
|
413
|
-
return f"跨CLI调用失败: {target_cli} -> {task}"
|
|
414
|
-
|
|
415
|
-
async def on_before_execute(self, context: PluginContext) -> Optional[str]:
|
|
416
|
-
"""
|
|
417
|
-
执行前Plugin处理函数
|
|
418
|
-
|
|
419
|
-
Args:
|
|
420
|
-
context: Plugin上下文
|
|
421
|
-
|
|
422
|
-
Returns:
|
|
423
|
-
Optional[str]: 处理结果
|
|
424
|
-
"""
|
|
425
|
-
# 可以在这里预处理执行前的逻辑
|
|
426
|
-
return None
|
|
427
|
-
|
|
428
|
-
async def on_after_execute(self, context: PluginContext) -> Optional[str]:
|
|
429
|
-
"""
|
|
430
|
-
执行后Plugin处理函数
|
|
431
|
-
|
|
432
|
-
Args:
|
|
433
|
-
context: Plugin上下文
|
|
434
|
-
|
|
435
|
-
Returns:
|
|
436
|
-
Optional[str]: 处理结果
|
|
437
|
-
"""
|
|
438
|
-
# 可以在这里后处理执行后的结果
|
|
439
|
-
return None
|
|
440
|
-
|
|
441
|
-
async def on_code_generated(self, context: PluginContext) -> Optional[str]:
|
|
442
|
-
"""
|
|
443
|
-
代码生成Plugin处理函数
|
|
444
|
-
|
|
445
|
-
Args:
|
|
446
|
-
context: Plugin上下文
|
|
447
|
-
|
|
448
|
-
Returns:
|
|
449
|
-
Optional[str]: 处理结果
|
|
450
|
-
"""
|
|
451
|
-
# 可以在这里处理代码生成相关的跨CLI功能
|
|
452
|
-
return None
|
|
453
|
-
|
|
454
|
-
async def on_error_occurred(self, context: PluginContext) -> Optional[str]:
|
|
455
|
-
"""
|
|
456
|
-
错误发生Plugin处理函数
|
|
457
|
-
|
|
458
|
-
Args:
|
|
459
|
-
context: Plugin上下文
|
|
460
|
-
|
|
461
|
-
Returns:
|
|
462
|
-
Optional[str]: 处理结果
|
|
463
|
-
"""
|
|
464
|
-
# 可以在这里处理错误恢复逻辑
|
|
465
|
-
return None
|
|
466
|
-
|
|
467
|
-
async def on_file_created(self, context: PluginContext) -> Optional[str]:
|
|
468
|
-
"""
|
|
469
|
-
文件创建Plugin处理函数
|
|
470
|
-
|
|
471
|
-
Args:
|
|
472
|
-
context: Plugin上下文
|
|
473
|
-
|
|
474
|
-
Returns:
|
|
475
|
-
Optional[str]: 处理结果
|
|
476
|
-
"""
|
|
477
|
-
return None
|
|
478
|
-
|
|
479
|
-
async def on_before_save(self, context: PluginContext) -> Optional[str]:
|
|
480
|
-
"""
|
|
481
|
-
保存前Plugin处理函数
|
|
482
|
-
|
|
483
|
-
Args:
|
|
484
|
-
context: Plugin上下文
|
|
485
|
-
|
|
486
|
-
Returns:
|
|
487
|
-
Optional[str]: 处理结果
|
|
488
|
-
"""
|
|
489
|
-
return None
|
|
490
|
-
|
|
491
|
-
async def _execute_cross_cli_call(
|
|
492
|
-
self,
|
|
493
|
-
target_cli: str,
|
|
494
|
-
task: str,
|
|
495
|
-
context: PluginContext
|
|
496
|
-
) -> Optional[str]:
|
|
497
|
-
"""
|
|
498
|
-
执行跨CLI调用
|
|
499
|
-
|
|
500
|
-
Args:
|
|
501
|
-
target_cli: 目标CLI工具
|
|
502
|
-
task: 要执行的任务
|
|
503
|
-
context: Plugin上下文
|
|
504
|
-
|
|
505
|
-
Returns:
|
|
506
|
-
Optional[str]: 执行结果
|
|
507
|
-
"""
|
|
508
|
-
try:
|
|
509
|
-
logger.info(f"执行跨CLI调用: {target_cli} -> {task}")
|
|
510
|
-
|
|
511
|
-
# 获取目标CLI适配器
|
|
512
|
-
target_adapter = self.get_adapter(target_cli)
|
|
513
|
-
|
|
514
|
-
if not target_adapter:
|
|
515
|
-
logger.warning(f"目标CLI适配器不可用: {target_cli}")
|
|
516
|
-
return self._format_error_result(
|
|
517
|
-
target_cli,
|
|
518
|
-
f"目标CLI工具 '{target_cli}' 不可用或未安装"
|
|
519
|
-
)
|
|
520
|
-
|
|
521
|
-
if not target_adapter.is_available():
|
|
522
|
-
logger.warning(f"目标CLI工具不可用: {target_cli}")
|
|
523
|
-
return self._format_error_result(
|
|
524
|
-
target_cli,
|
|
525
|
-
f"目标CLI工具 '{target_cli}' 当前不可用"
|
|
526
|
-
)
|
|
527
|
-
|
|
528
|
-
# 构建执行上下文
|
|
529
|
-
execution_context = {
|
|
530
|
-
'source_cli': self.cli_name,
|
|
531
|
-
'target_cli': target_cli,
|
|
532
|
-
'original_task': task,
|
|
533
|
-
'plugin_context': context.__dict__,
|
|
534
|
-
'timestamp': datetime.now().isoformat()
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
# 执行任务
|
|
538
|
-
result = await target_adapter.execute_task(task, execution_context)
|
|
539
|
-
|
|
540
|
-
# 记录成功的跨CLI调用
|
|
541
|
-
self.processed_requests.append({
|
|
542
|
-
'type': 'cross_cli_execution',
|
|
543
|
-
'target_cli': target_cli,
|
|
544
|
-
'task': task,
|
|
545
|
-
'success': True,
|
|
546
|
-
'result_length': len(result),
|
|
547
|
-
'timestamp': datetime.now().isoformat()
|
|
548
|
-
})
|
|
549
|
-
|
|
550
|
-
# 格式化结果
|
|
551
|
-
formatted_result = self._format_result(target_cli, result)
|
|
552
|
-
|
|
553
|
-
logger.info(f"跨CLI调用成功: {target_cli}")
|
|
554
|
-
return formatted_result
|
|
555
|
-
|
|
556
|
-
except Exception as e:
|
|
557
|
-
logger.error(f"跨CLI调用失败: {target_cli}, {e}")
|
|
558
|
-
self.record_error()
|
|
559
|
-
|
|
560
|
-
self.processed_requests.append({
|
|
561
|
-
'type': 'cross_cli_execution',
|
|
562
|
-
'target_cli': target_cli,
|
|
563
|
-
'task': task,
|
|
564
|
-
'success': False,
|
|
565
|
-
'error': str(e),
|
|
566
|
-
'timestamp': datetime.now().isoformat()
|
|
567
|
-
})
|
|
568
|
-
|
|
569
|
-
return self._format_error_result(target_cli, str(e))
|
|
570
|
-
|
|
571
|
-
def _format_result(
|
|
572
|
-
self,
|
|
573
|
-
target_cli: str,
|
|
574
|
-
result: str
|
|
575
|
-
) -> str:
|
|
576
|
-
"""
|
|
577
|
-
格式化成功的跨CLI调用结果
|
|
578
|
-
|
|
579
|
-
Args:
|
|
580
|
-
target_cli: 目标CLI工具
|
|
581
|
-
result: 执行结果
|
|
582
|
-
|
|
583
|
-
Returns:
|
|
584
|
-
str: 格式化的结果
|
|
585
|
-
"""
|
|
586
|
-
return f"""## 🔗 跨CLI调用结果
|
|
587
|
-
|
|
588
|
-
**源工具**: QwenCode CLI
|
|
589
|
-
**目标工具**: {target_cli.upper()}
|
|
590
|
-
**执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
591
|
-
|
|
592
|
-
---
|
|
593
|
-
|
|
594
|
-
{result}
|
|
595
|
-
|
|
596
|
-
---
|
|
597
|
-
|
|
598
|
-
*此结果由跨CLI集成系统通过QwenCode Class Inheritance提供*"""
|
|
599
|
-
|
|
600
|
-
def _format_error_result(
|
|
601
|
-
self,
|
|
602
|
-
target_cli: str,
|
|
603
|
-
error_message: str
|
|
604
|
-
) -> str:
|
|
605
|
-
"""
|
|
606
|
-
格式化错误的跨CLI调用结果
|
|
607
|
-
|
|
608
|
-
Args:
|
|
609
|
-
target_cli: 目标CLI工具
|
|
610
|
-
error_message: 错误信息
|
|
611
|
-
|
|
612
|
-
Returns:
|
|
613
|
-
str: 格式化的错误结果
|
|
614
|
-
"""
|
|
615
|
-
return f"""## ❌ 跨CLI调用失败
|
|
616
|
-
|
|
617
|
-
**源工具**: QwenCode CLI
|
|
618
|
-
**目标工具**: {target_cli.upper()}
|
|
619
|
-
**错误信息**: {error_message}
|
|
620
|
-
**失败时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
621
|
-
|
|
622
|
-
请检查目标CLI工具是否正确安装和配置。
|
|
623
|
-
|
|
624
|
-
---
|
|
625
|
-
|
|
626
|
-
*此错误由跨CLI集成系统报告*"""
|
|
627
|
-
|
|
628
|
-
def is_available(self) -> bool:
|
|
629
|
-
"""
|
|
630
|
-
检查适配器是否可用
|
|
631
|
-
|
|
632
|
-
Returns:
|
|
633
|
-
bool: 是否可用
|
|
634
|
-
"""
|
|
635
|
-
return self.plugins_loaded and self._check_qwencode_environment()
|
|
636
|
-
|
|
637
|
-
async def health_check(self) -> Dict[str, Any]:
|
|
638
|
-
"""
|
|
639
|
-
健康检查
|
|
640
|
-
|
|
641
|
-
Returns:
|
|
642
|
-
Dict[str, Any]: 健康状态
|
|
643
|
-
"""
|
|
644
|
-
base_health = await super().health_check()
|
|
645
|
-
|
|
646
|
-
qwencode_health = {
|
|
647
|
-
'plugins_loaded': self.plugins_loaded,
|
|
648
|
-
'plugin_calls_count': self.plugin_calls_count,
|
|
649
|
-
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
650
|
-
'processed_requests_count': len(self.processed_requests),
|
|
651
|
-
'config_file': self.config_file,
|
|
652
|
-
'config_exists': os.path.exists(self.config_file),
|
|
653
|
-
'plugin_handlers': list(self.plugin_handlers.keys()),
|
|
654
|
-
'inheritance_setup_complete': self.inheritance_setup_complete,
|
|
655
|
-
'base_class_loaded': self.base_class is not None
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
# 检查环境
|
|
659
|
-
try:
|
|
660
|
-
qwencode_health['qwencode_environment'] = self._check_qwencode_environment()
|
|
661
|
-
except Exception as e:
|
|
662
|
-
qwencode_health['qwencode_environment_error'] = str(e)
|
|
663
|
-
|
|
664
|
-
# 合并基础健康信息
|
|
665
|
-
base_health.update(qwencode_health)
|
|
666
|
-
return base_health
|
|
667
|
-
|
|
668
|
-
def get_statistics(self) -> Dict[str, Any]:
|
|
669
|
-
"""
|
|
670
|
-
获取适配器统计信息
|
|
671
|
-
|
|
672
|
-
Returns:
|
|
673
|
-
Dict[str, Any]: 统计信息
|
|
674
|
-
"""
|
|
675
|
-
base_stats = super().get_statistics()
|
|
676
|
-
|
|
677
|
-
qwencode_stats = {
|
|
678
|
-
'plugins_loaded': self.plugins_loaded,
|
|
679
|
-
'plugin_calls_count': self.plugin_calls_count,
|
|
680
|
-
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
681
|
-
'success_rate': self._calculate_success_rate(),
|
|
682
|
-
'last_activity': self._get_last_activity(),
|
|
683
|
-
'supported_plugins': list(self.plugin_handlers.keys())
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
base_stats.update(qwencode_stats)
|
|
687
|
-
return base_stats
|
|
688
|
-
|
|
689
|
-
def _calculate_success_rate(self) -> float:
|
|
690
|
-
"""
|
|
691
|
-
计算成功率
|
|
692
|
-
|
|
693
|
-
Returns:
|
|
694
|
-
float: 成功率 (0.0 - 1.0)
|
|
695
|
-
"""
|
|
696
|
-
total_cross_cli = self.cross_cli_calls_count
|
|
697
|
-
|
|
698
|
-
if total_cross_cli == 0:
|
|
699
|
-
return 1.0
|
|
700
|
-
|
|
701
|
-
successful_calls = sum(
|
|
702
|
-
1 for req in self.processed_requests
|
|
703
|
-
if req.get('type') == 'cross_cli_execution' and req.get('success')
|
|
704
|
-
)
|
|
705
|
-
|
|
706
|
-
return successful_calls / total_cross_cli
|
|
707
|
-
|
|
708
|
-
def _get_last_activity(self) -> Optional[str]:
|
|
709
|
-
"""
|
|
710
|
-
获取最后活动时间
|
|
711
|
-
|
|
712
|
-
Returns:
|
|
713
|
-
Optional[str]: 最后活动时间戳
|
|
714
|
-
"""
|
|
715
|
-
if not self.processed_requests:
|
|
716
|
-
return None
|
|
717
|
-
|
|
718
|
-
return max(req['timestamp'] for req in self.processed_requests)
|
|
719
|
-
|
|
720
|
-
async def execute_task(self, task: str, context: Dict[str, Any]) -> str:
|
|
721
|
-
"""
|
|
722
|
-
执行跨CLI任务 - QwenCode适配器的具体实现
|
|
723
|
-
|
|
724
|
-
Args:
|
|
725
|
-
task: 要执行的任务描述
|
|
726
|
-
context: 执行上下文信息
|
|
727
|
-
|
|
728
|
-
Returns:
|
|
729
|
-
str: 任务执行结果
|
|
730
|
-
"""
|
|
731
|
-
try:
|
|
732
|
-
# QwenCode适配器的任务执行主要是通过Plugin系统
|
|
733
|
-
# 这里创建一个模拟的Plugin上下文来处理任务
|
|
734
|
-
plugin_context = PluginContext(
|
|
735
|
-
prompt=task,
|
|
736
|
-
metadata=context.get('metadata', {})
|
|
737
|
-
)
|
|
738
|
-
|
|
739
|
-
# 检查是否为跨CLI调用
|
|
740
|
-
intent = self.parser.parse_intent(task, "qwencode")
|
|
741
|
-
if intent.is_cross_cli and intent.target_cli != self.cli_name:
|
|
742
|
-
# 执行跨CLI调用
|
|
743
|
-
result = await self._execute_cross_cli_call(
|
|
744
|
-
intent.target_cli,
|
|
745
|
-
intent.task,
|
|
746
|
-
plugin_context
|
|
747
|
-
)
|
|
748
|
-
return result or f"QwenCode Inheritance适配器处理了任务: {task}"
|
|
749
|
-
else:
|
|
750
|
-
# 本地QwenCode任务处理
|
|
751
|
-
return f"QwenCode Inheritance适配器本地处理: {task}"
|
|
752
|
-
|
|
753
|
-
except Exception as e:
|
|
754
|
-
logger.error(f"执行任务失败: {task}, 错误: {e}")
|
|
755
|
-
self.record_error()
|
|
756
|
-
return f"任务执行失败: {str(e)}"
|
|
757
|
-
|
|
758
|
-
async def cleanup(self) -> bool:
|
|
759
|
-
"""
|
|
760
|
-
清理适配器资源
|
|
761
|
-
|
|
762
|
-
Returns:
|
|
763
|
-
bool: 清理是否成功
|
|
764
|
-
"""
|
|
765
|
-
try:
|
|
766
|
-
# 清理统计信息
|
|
767
|
-
self.processed_requests.clear()
|
|
768
|
-
|
|
769
|
-
# 清理插件(如果需要)
|
|
770
|
-
# 这里可以实现插件卸载逻辑
|
|
771
|
-
|
|
772
|
-
logger.info("QwenCode Class Inheritance适配器清理完成")
|
|
773
|
-
return True
|
|
774
|
-
|
|
775
|
-
except Exception as e:
|
|
776
|
-
logger.error(f"清理QwenCode Class Inheritance适配器失败: {e}")
|
|
777
|
-
return False
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
# 创建全局适配器实例
|
|
781
|
-
_global_adapter: Optional[QwenCodeInheritanceAdapter] = None
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
def get_qwencode_inheritance_adapter() -> QwenCodeInheritanceAdapter:
|
|
785
|
-
"""
|
|
786
|
-
获取QwenCode Inheritance适配器实例
|
|
787
|
-
|
|
788
|
-
Returns:
|
|
789
|
-
QwenCodeInheritanceAdapter: 适配器实例
|
|
790
|
-
"""
|
|
791
|
-
global _global_adapter
|
|
792
|
-
if _global_adapter is None:
|
|
793
|
-
_global_adapter = QwenCodeInheritanceAdapter()
|
|
794
|
-
# 异步初始化需要在调用时进行
|
|
795
|
-
return _global_adapter
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
# 便捷函数
|
|
799
|
-
async def initialize_qwencode_adapter() -> bool:
|
|
800
|
-
"""
|
|
801
|
-
初始化QwenCode Inheritance适配器
|
|
802
|
-
|
|
803
|
-
Returns:
|
|
804
|
-
bool: 初始化是否成功
|
|
805
|
-
"""
|
|
806
|
-
adapter = get_qwencode_inheritance_adapter()
|
|
807
|
-
return await adapter.initialize()
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
def is_qwencode_adapter_available() -> bool:
|
|
811
|
-
"""
|
|
812
|
-
检查QwenCode Inheritance适配器是否可用
|
|
813
|
-
|
|
814
|
-
Returns:
|
|
815
|
-
bool: 是否可用
|
|
816
|
-
"""
|
|
817
|
-
adapter = get_qwencode_inheritance_adapter()
|
|
818
|
-
return adapter.is_available()
|