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.
Files changed (102) hide show
  1. package/README.en.md +306 -300
  2. package/README.md +469 -301
  3. package/package.json +97 -81
  4. package/scripts/publish.js +268 -0
  5. package/scripts/simple-publish.js +59 -0
  6. package/src/index.js +12 -0
  7. package/test/enhanced-main-alignment.test.js +298 -0
  8. package/test/hook-system-integration-test.js +307 -0
  9. package/test/natural-language-skills-test.js +320 -0
  10. package/test/nl-integration-test.js +179 -0
  11. package/test/parameter-parsing-test.js +143 -0
  12. package/test/real-test.js +435 -0
  13. package/test/system-compatibility-test.js +447 -0
  14. package/test/tdd-fixes-test.js +211 -0
  15. package/test/third-party-skills-test.js +321 -0
  16. package/test/tool-selection-integration-test.js +157 -0
  17. package/test/unit/cli-scanner.test.js +291 -0
  18. package/test/unit/cross-cli-executor.test.js +399 -0
  19. package/src/adapters/claude/__init__.py +0 -13
  20. package/src/adapters/claude/claude_skills_integration.py +0 -609
  21. package/src/adapters/claude/hook_adapter.py +0 -663
  22. package/src/adapters/claude/install_claude_integration.py +0 -265
  23. package/src/adapters/claude/skills_hook_adapter.py +0 -841
  24. package/src/adapters/claude/standalone_claude_adapter.py +0 -384
  25. package/src/adapters/cline/__init__.py +0 -20
  26. package/src/adapters/cline/config.py +0 -108
  27. package/src/adapters/cline/install_cline_integration.py +0 -617
  28. package/src/adapters/cline/mcp_server.py +0 -713
  29. package/src/adapters/cline/standalone_cline_adapter.py +0 -459
  30. package/src/adapters/codebuddy/__init__.py +0 -13
  31. package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
  32. package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
  33. package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
  34. package/src/adapters/codebuddy/skills_integration.py +0 -395
  35. package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
  36. package/src/adapters/codex/__init__.py +0 -11
  37. package/src/adapters/codex/base.py +0 -46
  38. package/src/adapters/codex/install_codex_integration.py +0 -311
  39. package/src/adapters/codex/mcp_server.py +0 -493
  40. package/src/adapters/codex/natural_language_parser.py +0 -82
  41. package/src/adapters/codex/slash_command_adapter.py +0 -326
  42. package/src/adapters/codex/standalone_codex_adapter.py +0 -362
  43. package/src/adapters/copilot/__init__.py +0 -13
  44. package/src/adapters/copilot/install_copilot_integration.py +0 -564
  45. package/src/adapters/copilot/mcp_adapter.py +0 -772
  46. package/src/adapters/copilot/mcp_server.py +0 -168
  47. package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
  48. package/src/adapters/gemini/__init__.py +0 -13
  49. package/src/adapters/gemini/extension_adapter.py +0 -690
  50. package/src/adapters/gemini/install_gemini_integration.py +0 -257
  51. package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
  52. package/src/adapters/iflow/__init__.py +0 -7
  53. package/src/adapters/iflow/hook_adapter.py +0 -1038
  54. package/src/adapters/iflow/hook_installer.py +0 -536
  55. package/src/adapters/iflow/install_iflow_integration.py +0 -271
  56. package/src/adapters/iflow/official_hook_adapter.py +0 -1272
  57. package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
  58. package/src/adapters/iflow/workflow_adapter.py +0 -793
  59. package/src/adapters/qoder/hook_installer.py +0 -732
  60. package/src/adapters/qoder/install_qoder_integration.py +0 -265
  61. package/src/adapters/qoder/notification_hook_adapter.py +0 -863
  62. package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
  63. package/src/adapters/qwen/__init__.py +0 -17
  64. package/src/adapters/qwencode/__init__.py +0 -13
  65. package/src/adapters/qwencode/inheritance_adapter.py +0 -818
  66. package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
  67. package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
  68. package/src/atomic_collaboration_handler.py +0 -461
  69. package/src/cli_collaboration_agent.py +0 -697
  70. package/src/collaboration/hooks.py +0 -315
  71. package/src/core/__init__.py +0 -21
  72. package/src/core/ai_environment_scanner.py +0 -331
  73. package/src/core/base_adapter.py +0 -220
  74. package/src/core/cli_hook_integration.py +0 -406
  75. package/src/core/cross_cli_executor.py +0 -713
  76. package/src/core/cross_cli_mapping.py +0 -1165
  77. package/src/core/cross_platform_encoding.py +0 -365
  78. package/src/core/cross_platform_safe_cli.py +0 -894
  79. package/src/core/direct_cli_executor.py +0 -805
  80. package/src/core/direct_cli_hook_system.py +0 -958
  81. package/src/core/enhanced_init_processor.py +0 -467
  82. package/src/core/graceful_cli_executor.py +0 -912
  83. package/src/core/md_enhancer.py +0 -342
  84. package/src/core/md_generator.py +0 -619
  85. package/src/core/models.py +0 -218
  86. package/src/core/parser.py +0 -108
  87. package/src/core/real_cli_hook_system.py +0 -852
  88. package/src/core/real_cross_cli_system.py +0 -925
  89. package/src/core/verified_cross_cli_system.py +0 -961
  90. package/src/deploy.js +0 -737
  91. package/src/enhanced-main.js +0 -626
  92. package/src/enhanced_deploy.js +0 -303
  93. package/src/enhanced_universal_cli_setup.py +0 -930
  94. package/src/kimi_wrapper.py +0 -104
  95. package/src/main.js +0 -1309
  96. package/src/shell_integration.py +0 -398
  97. package/src/simple-main.js +0 -315
  98. package/src/smart_router_creator.py +0 -323
  99. package/src/universal_cli_setup.py +0 -1289
  100. package/src/utils/__init__.py +0 -12
  101. package/src/utils/cli_detector.py +0 -445
  102. package/src/utils/file_utils.py +0 -246
@@ -1,793 +0,0 @@
1
- """
2
- iFlow CLI Workflow Pipeline适配器
3
-
4
- 通过iFlow CLI的Workflow Pipeline系统实现跨CLI调用功能。
5
- 基于通用workflow插件架构,支持灵活的工作流扩展。
6
- """
7
-
8
- import asyncio
9
- import json
10
- import logging
11
- from datetime import datetime
12
- from pathlib import Path
13
- from typing import Dict, Any, Optional, List, Union
14
-
15
- from src.core.base_adapter import BaseCrossCLIAdapter
16
- from src.core.parser import NaturalLanguageParser
17
-
18
- # 配置日志
19
- logger = logging.getLogger(__name__)
20
-
21
-
22
- class WorkflowContext:
23
- """iFlow CLI工作流上下文"""
24
-
25
- def __init__(self, workflow_id: str = "", stage: str = "", data: Dict = None):
26
- self.workflow_id = workflow_id
27
- self.stage = stage
28
- self.data = data or {}
29
- self.metadata = {
30
- 'user_id': 'default_user',
31
- 'session_id': '',
32
- 'pipeline_config': {}
33
- }
34
- self.pipeline_name = "cross-cli-integration"
35
- self.version = "1.0.0"
36
- self.start_time = datetime.now()
37
- self.status = "pending"
38
-
39
-
40
- class WorkflowStage:
41
- """工作流阶段"""
42
-
43
- def __init__(self, name: str, description: str = "", required: bool = True, timeout: int = 30):
44
- self.name = name
45
- self.description = description
46
- self.required = required
47
- self.timeout = timeout
48
- self.status = "pending"
49
- self.result = None
50
- self.error = None
51
- self.start_time = None
52
- self.end_time = None
53
-
54
-
55
- class IFlowWorkflowAdapter(BaseCrossCLIAdapter):
56
- """
57
- iFlow CLI Workflow Pipeline适配器
58
-
59
- 通过iFlow CLI的Workflow Pipeline系统实现跨CLI调用功能。
60
- 基于工作流的无损扩展实现。
61
-
62
- Pipeline机制:
63
- - on_workflow_start: 工作流开始时触发
64
- - on_stage_complete: 阶段完成时触发
65
- - on_workflow_success: 工作流成功完成时触发
66
- - on_workflow_error: 工作流错误时触发
67
- - on_pipeline_ready: 流水线就绪时触发
68
- """
69
-
70
- def __init__(self, cli_name: str = "iflow"):
71
- super().__init__(cli_name)
72
-
73
- # Pipeline相关属性
74
- self.pipeline_stages: List[WorkflowStage] = []
75
- self.workflow_hooks: Dict[str, callable] = {}
76
- self.processed_workflows: List[Dict] = []
77
- self.workflow_executions: List[Dict] = []
78
- self.task_queue: Optional[asyncio.Queue] = None
79
-
80
- # 统计信息
81
- self.stages_processed = 0
82
- self.cross_cli_calls_count = 0
83
- self.workflow_count = 0
84
-
85
- # 配置
86
- self.pipeline_config: Dict = {}
87
- self.workflow_config: Dict = {}
88
-
89
- # 组件
90
- self.parser = NaturalLanguageParser()
91
-
92
- logger.info("iFlow Workflow Pipeline适配器初始化完成")
93
-
94
- async def initialize(self) -> bool:
95
- """
96
- 初始化适配器
97
-
98
- Returns:
99
- bool: 初始化是否成功
100
- """
101
- try:
102
- logger.info("开始初始化iFlow Workflow Pipeline适配器...")
103
-
104
- # 1. 加载Pipeline配置
105
- if not await self._load_pipeline_config():
106
- logger.error("Pipeline配置加载失败")
107
- return False
108
-
109
- # 2. 初始化工作流阶段
110
- if not await self._initialize_workflow_stages():
111
- logger.error("工作流阶段初始化失败")
112
- return False
113
-
114
- # 3. 注册工作流Hooks
115
- if not await self._register_workflow_hooks():
116
- logger.error("工作流Hooks注册失败")
117
- return False
118
-
119
- # 4. 初始化任务队列
120
- if not await self._initialize_task_queue():
121
- logger.error("任务队列初始化失败")
122
- return False
123
-
124
- # 5. 创建工作流配置目录
125
- await self._ensure_config_directory()
126
-
127
- logger.info("iFlow Workflow Pipeline适配器初始化成功")
128
- return True
129
-
130
- except Exception as e:
131
- logger.error(f"初始化iFlow Workflow Pipeline适配器失败: {e}")
132
- return False
133
-
134
- async def _load_pipeline_config(self) -> bool:
135
- """
136
- 加载Pipeline配置
137
-
138
- Returns:
139
- bool: 加载是否成功
140
- """
141
- try:
142
- config_path = Path(__file__).parent / "config.json"
143
-
144
- if config_path.exists():
145
- with open(config_path, 'r', encoding='utf-8') as f:
146
- config = json.load(f)
147
-
148
- self.pipeline_config = config
149
- self.workflow_config = config.get('workflow', {})
150
- logger.info("Pipeline配置加载成功")
151
- return True
152
- else:
153
- logger.warning("Pipeline配置文件不存在,使用默认配置")
154
- self.pipeline_config = self._get_default_config()
155
- return True
156
-
157
- except Exception as e:
158
- logger.error(f"加载Pipeline配置失败: {e}")
159
- return False
160
-
161
- def _get_default_config(self) -> Dict:
162
- """获取默认配置"""
163
- return {
164
- "adapter_name": "iFlow Workflow Pipeline Adapter",
165
- "pipeline_mechanism": "workflow_pipeline",
166
- "supported_clis": ["claude", "gemini", "qwencode", "qoder", "codebuddy", "codex"],
167
- "workflow": {
168
- "default_settings": {
169
- "parallel_execution": True,
170
- "error_handling": "continue",
171
- "retry_on_failure": True
172
- }
173
- }
174
- }
175
-
176
- async def _initialize_workflow_stages(self) -> bool:
177
- """
178
- 初始化工作流阶段
179
-
180
- Returns:
181
- bool: 初始化是否成功
182
- """
183
- try:
184
- stage_configs = self.workflow_config.get('pipeline_setup', {}).get('stages', [])
185
-
186
- default_stages = [
187
- WorkflowStage("input_validation", "输入数据验证", True, 5),
188
- WorkflowStage("cross_cli_detection", "跨CLI调用检测", True, 10),
189
- WorkflowStage("target_execution", "目标CLI执行", False, 25),
190
- WorkflowStage("result_processing", "结果处理", True, 8),
191
- WorkflowStage("output_formatting", "输出格式化", True, 3)
192
- ]
193
-
194
- # 如果配置中有阶段定义,使用配置中的定义
195
- if stage_configs:
196
- self.pipeline_stages = []
197
- for stage_config in stage_configs:
198
- stage = WorkflowStage(
199
- stage_config['name'],
200
- stage_config.get('description', ''),
201
- stage_config.get('required', True),
202
- stage_config.get('timeout', 30)
203
- )
204
- self.pipeline_stages.append(stage)
205
- else:
206
- self.pipeline_stages = default_stages
207
-
208
- logger.info(f"工作流阶段初始化完成,共{len(self.pipeline_stages)}个阶段")
209
- return True
210
-
211
- except Exception as e:
212
- logger.error(f"初始化工作流阶段失败: {e}")
213
- return False
214
-
215
- async def _register_workflow_hooks(self) -> bool:
216
- """
217
- 注册工作流Hooks
218
-
219
- Returns:
220
- bool: 注册是否成功
221
- """
222
- try:
223
- self.workflow_hooks = {
224
- 'on_workflow_start': self.on_workflow_start,
225
- 'on_stage_complete': self.on_stage_complete,
226
- 'on_workflow_success': self.on_workflow_success,
227
- 'on_workflow_error': self.on_workflow_error,
228
- 'on_pipeline_ready': self.on_pipeline_ready
229
- }
230
-
231
- logger.info("工作流Hooks注册成功")
232
- return True
233
-
234
- except Exception as e:
235
- logger.error(f"注册工作流Hooks失败: {e}")
236
- return False
237
-
238
- async def _initialize_task_queue(self) -> bool:
239
- """
240
- 初始化任务队列
241
-
242
- Returns:
243
- bool: 初始化是否成功
244
- """
245
- try:
246
- self.task_queue = asyncio.Queue()
247
- logger.info("任务队列初始化成功")
248
- return True
249
-
250
- except Exception as e:
251
- logger.error(f"初始化任务队列失败: {e}")
252
- return False
253
-
254
- async def _ensure_config_directory(self) -> None:
255
- """确保配置目录存在"""
256
- config_dir = Path.home() / ".config" / "iflow" / "adapters"
257
- config_dir.mkdir(parents=True, exist_ok=True)
258
-
259
- def is_available(self) -> bool:
260
- """
261
- 检查适配器是否可用
262
-
263
- Returns:
264
- bool: 是否可用
265
- """
266
- return (
267
- len(self.pipeline_stages) > 0 and
268
- len(self.workflow_hooks) > 0 and
269
- self.task_queue is not None
270
- )
271
-
272
- async def execute_task(self, task: str, context: Dict[str, Any]) -> str:
273
- """
274
- 执行工作流任务
275
-
276
- Args:
277
- task: 要执行的任务
278
- context: 执行上下文
279
-
280
- Returns:
281
- str: 执行结果
282
- """
283
- try:
284
- logger.info(f"执行iFlow工作流任务: {task}")
285
-
286
- # 创建工作流上下文
287
- workflow_context = WorkflowContext(
288
- workflow_id=context.get('workflow_id', f'workflow-{datetime.now().timestamp()}'),
289
- stage="execution",
290
- data={"task": task, **context}
291
- )
292
-
293
- # 执行工作流
294
- result = await self._execute_workflow(workflow_context)
295
-
296
- return result
297
-
298
- except Exception as e:
299
- logger.error(f"执行工作流任务失败: {e}")
300
- return f"工作流执行失败: {str(e)}"
301
-
302
- # ==================== Workflow Hook处理器 ====================
303
-
304
- async def on_workflow_start(self, context: WorkflowContext) -> Optional[str]:
305
- """
306
- 工作流开始Hook
307
-
308
- Args:
309
- context: 工作流上下文
310
-
311
- Returns:
312
- Optional[str]: 处理结果
313
- """
314
- try:
315
- self.workflow_count += 1
316
- self.stages_processed += 1
317
-
318
- # 记录工作流开始
319
- workflow_record = {
320
- 'type': 'workflow_start',
321
- 'workflow_id': context.workflow_id,
322
- 'stage': context.stage,
323
- 'data': context.data,
324
- 'metadata': context.metadata,
325
- 'timestamp': datetime.now().isoformat()
326
- }
327
- self.processed_workflows.append(workflow_record)
328
-
329
- logger.info(f"工作流开始: {context.workflow_id}")
330
-
331
- # 检测跨CLI调用意图
332
- user_input = context.data.get('prompt', context.data.get('task', ''))
333
- if not user_input:
334
- return None
335
-
336
- intent = self.parser.parse_intent(user_input, "iflow")
337
-
338
- if intent.is_cross_cli and intent.target_cli != self.cli_name:
339
- # 执行跨CLI调用
340
- result = await self._execute_cross_cli_workflow(
341
- intent.target_cli,
342
- intent.task,
343
- context
344
- )
345
-
346
- if result:
347
- self.cross_cli_calls_count += 1
348
- return result
349
-
350
- return None # 继续正常工作流
351
-
352
- except Exception as e:
353
- logger.error(f"工作流开始Hook处理失败: {e}")
354
- self.record_error()
355
- return None
356
-
357
- async def on_stage_complete(self, context: WorkflowContext, stage_result: Any) -> Optional[str]:
358
- """
359
- 阶段完成Hook
360
-
361
- Args:
362
- context: 工作流上下文
363
- stage_result: 阶段结果
364
-
365
- Returns:
366
- Optional[str]: 处理结果
367
- """
368
- try:
369
- self.stages_processed += 1
370
-
371
- # 记录阶段完成
372
- stage_record = {
373
- 'type': 'stage_complete',
374
- 'workflow_id': context.workflow_id,
375
- 'stage': context.stage,
376
- 'result': str(stage_result) if stage_result else None,
377
- 'timestamp': datetime.now().isoformat()
378
- }
379
- self.processed_workflows.append(stage_record)
380
-
381
- logger.debug(f"工作流阶段完成: {context.workflow_id} - {context.stage}")
382
- return None
383
-
384
- except Exception as e:
385
- logger.error(f"阶段完成Hook处理失败: {e}")
386
- self.record_error()
387
- return None
388
-
389
- async def on_workflow_success(self, context: WorkflowContext, final_result: Any) -> Optional[str]:
390
- """
391
- 工作流成功Hook
392
-
393
- Args:
394
- context: 工作流上下文
395
- final_result: 最终结果
396
-
397
- Returns:
398
- Optional[str]: 处理结果
399
- """
400
- try:
401
- # 记录工作流成功
402
- success_record = {
403
- 'type': 'workflow_success',
404
- 'workflow_id': context.workflow_id,
405
- 'result': str(final_result) if final_result else None,
406
- 'duration': (datetime.now() - context.start_time).total_seconds(),
407
- 'timestamp': datetime.now().isoformat()
408
- }
409
- self.processed_workflows.append(success_record)
410
-
411
- logger.info(f"工作流成功完成: {context.workflow_id}")
412
- return None
413
-
414
- except Exception as e:
415
- logger.error(f"工作流成功Hook处理失败: {e}")
416
- self.record_error()
417
- return None
418
-
419
- async def on_workflow_error(self, context: WorkflowContext, error: Exception) -> Optional[str]:
420
- """
421
- 工作流错误Hook
422
-
423
- Args:
424
- context: 工作流上下文
425
- error: 错误信息
426
-
427
- Returns:
428
- Optional[str]: 处理结果
429
- """
430
- try:
431
- # 记录工作流错误
432
- error_record = {
433
- 'type': 'workflow_error',
434
- 'workflow_id': context.workflow_id,
435
- 'error': str(error),
436
- 'error_type': type(error).__name__,
437
- 'timestamp': datetime.now().isoformat()
438
- }
439
- self.processed_workflows.append(error_record)
440
-
441
- logger.error(f"工作流执行错误: {context.workflow_id} - {error}")
442
- return None
443
-
444
- except Exception as e:
445
- logger.error(f"工作流错误Hook处理失败: {e}")
446
- self.record_error()
447
- return None
448
-
449
- async def on_pipeline_ready(self, pipeline_config: Dict) -> Optional[str]:
450
- """
451
- 流水线就绪Hook
452
-
453
- Args:
454
- pipeline_config: 流水线配置
455
-
456
- Returns:
457
- Optional[str]: 处理结果
458
- """
459
- try:
460
- logger.info("iFlow流水线已就绪")
461
- return None
462
-
463
- except Exception as e:
464
- logger.error(f"流水线就绪Hook处理失败: {e}")
465
- self.record_error()
466
- return None
467
-
468
- # ==================== 跨CLI功能 ====================
469
-
470
- async def _execute_cross_cli_workflow(
471
- self,
472
- target_cli: str,
473
- task: str,
474
- context: WorkflowContext
475
- ) -> Optional[str]:
476
- """
477
- 执行跨CLI工作流
478
-
479
- Args:
480
- target_cli: 目标CLI工具
481
- task: 要执行的任务
482
- context: 工作流上下文
483
-
484
- Returns:
485
- Optional[str]: 执行结果
486
- """
487
- try:
488
- logger.info(f"执行跨CLI工作流: {target_cli} -> {task}")
489
-
490
- # 记录跨CLI调用
491
- workflow_execution = {
492
- 'workflow_id': context.workflow_id,
493
- 'target_cli': target_cli,
494
- 'task': task,
495
- 'stage': context.stage,
496
- 'timestamp': datetime.now().isoformat()
497
- }
498
- self.workflow_executions.append(workflow_execution)
499
-
500
- # 获取目标CLI适配器
501
- target_adapter = self.get_adapter(target_cli)
502
-
503
- if not target_adapter:
504
- logger.warning(f"目标CLI适配器不可用: {target_cli}")
505
- return self._format_workflow_error(
506
- target_cli,
507
- task,
508
- f"目标CLI工具 '{target_cli}' 不可用或未安装"
509
- )
510
-
511
- if not target_adapter.is_available():
512
- logger.warning(f"目标CLI工具不可用: {target_cli}")
513
- return self._format_workflow_error(
514
- target_cli,
515
- task,
516
- f"目标CLI工具 '{target_cli}' 当前不可用"
517
- )
518
-
519
- # 构建执行上下文
520
- execution_context = {
521
- 'source_cli': self.cli_name,
522
- 'target_cli': target_cli,
523
- 'original_task': task,
524
- 'workflow_context': context.__dict__,
525
- 'timestamp': datetime.now().isoformat()
526
- }
527
-
528
- # 执行任务
529
- result = await target_adapter.execute_task(task, execution_context)
530
-
531
- # 记录成功的跨CLI调用
532
- self.processed_requests.append({
533
- 'type': 'cross_cli_workflow_execution',
534
- 'target_cli': target_cli,
535
- 'task': task,
536
- 'workflow_id': context.workflow_id,
537
- 'success': True,
538
- 'result_length': len(result),
539
- 'timestamp': datetime.now().isoformat()
540
- })
541
-
542
- # 格式化结果
543
- formatted_result = self._format_workflow_result(target_cli, result, context)
544
-
545
- logger.info(f"跨CLI工作流执行成功: {target_cli}")
546
- return formatted_result
547
-
548
- except Exception as e:
549
- logger.error(f"跨CLI工作流执行失败: {target_cli}, {e}")
550
-
551
- # 记录失败的跨CLI调用
552
- self.processed_requests.append({
553
- 'type': 'cross_cli_workflow_execution',
554
- 'target_cli': target_cli,
555
- 'task': task,
556
- 'workflow_id': context.workflow_id,
557
- 'success': False,
558
- 'error': str(e),
559
- 'timestamp': datetime.now().isoformat()
560
- })
561
-
562
- return self._format_workflow_error(target_cli, task, str(e))
563
-
564
- async def _execute_workflow(self, context: WorkflowContext) -> str:
565
- """
566
- 执行工作流
567
-
568
- Args:
569
- context: 工作流上下文
570
-
571
- Returns:
572
- str: 执行结果
573
- """
574
- try:
575
- # 触发工作流开始Hook
576
- start_result = await self.on_workflow_start(context)
577
- if start_result:
578
- return start_result
579
-
580
- # 执行各个阶段
581
- final_result = None
582
- for stage in self.pipeline_stages:
583
- stage_context = WorkflowContext(
584
- workflow_id=context.workflow_id,
585
- stage=stage.name,
586
- data=context.data
587
- )
588
-
589
- # 执行阶段
590
- stage_result = await self._execute_stage(stage, stage_context)
591
-
592
- # 触发阶段完成Hook
593
- await self.on_stage_complete(stage_context, stage_result)
594
-
595
- if stage_result is not None:
596
- final_result = stage_result
597
-
598
- # 触发工作流成功Hook
599
- await self.on_workflow_success(context, final_result)
600
-
601
- return final_result or "工作流执行完成"
602
-
603
- except Exception as e:
604
- # 触发工作流错误Hook
605
- await self.on_workflow_error(context, e)
606
- raise
607
-
608
- async def _execute_stage(self, stage: WorkflowStage, context: WorkflowContext) -> Any:
609
- """
610
- 执行工作流阶段
611
-
612
- Args:
613
- stage: 工作流阶段
614
- context: 工作流上下文
615
-
616
- Returns:
617
- Any: 阶段结果
618
- """
619
- try:
620
- stage.start_time = datetime.now()
621
- stage.status = "running"
622
-
623
- # 这里可以根据阶段名称执行不同的逻辑
624
- if stage.name == "cross_cli_detection":
625
- return await self._stage_cross_cli_detection(context)
626
- elif stage.name == "target_execution":
627
- return await self._stage_target_execution(context)
628
- elif stage.name == "result_processing":
629
- return await self._stage_result_processing(context)
630
- elif stage.name == "output_formatting":
631
- return await self._stage_output_formatting(context)
632
- else:
633
- # 默认处理
634
- return f"阶段 {stage.name} 执行完成"
635
-
636
- except Exception as e:
637
- stage.status = "failed"
638
- stage.error = str(e)
639
- raise
640
- finally:
641
- stage.end_time = datetime.now()
642
- if stage.error is None:
643
- stage.status = "completed"
644
-
645
- async def _stage_cross_cli_detection(self, context: WorkflowContext) -> Any:
646
- """跨CLI检测阶段"""
647
- user_input = context.data.get('prompt', context.data.get('task', ''))
648
- intent = self.parser.parse_intent(user_input, "iflow")
649
- return intent
650
-
651
- async def _stage_target_execution(self, context: WorkflowContext) -> Any:
652
- """目标执行阶段"""
653
- # 这个阶段的逻辑在on_workflow_start中已经处理
654
- return None
655
-
656
- async def _stage_result_processing(self, context: WorkflowContext) -> Any:
657
- """结果处理阶段"""
658
- return "结果处理完成"
659
-
660
- async def _stage_output_formatting(self, context: WorkflowContext) -> Any:
661
- """输出格式化阶段"""
662
- return "输出格式化完成"
663
-
664
- def _format_workflow_result(
665
- self,
666
- target_cli: str,
667
- result: str,
668
- context: WorkflowContext
669
- ) -> str:
670
- """
671
- 格式化工作流结果
672
-
673
- Args:
674
- target_cli: 目标CLI工具
675
- result: 执行结果
676
- context: 工作流上下文
677
-
678
- Returns:
679
- str: 格式化的结果
680
- """
681
- return f"""## 🔄 跨CLI工作流结果
682
-
683
- **源工作流**: iFlow Pipeline ({context.workflow_id})
684
- **目标CLI**: {target_cli.upper()}
685
- **工作流阶段**: {context.stage}
686
- **执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
687
-
688
- ---
689
-
690
- {result}
691
-
692
- ---
693
-
694
- *此结果由iFlow跨CLI集成系统通过Workflow Pipeline提供*"""
695
-
696
- def _format_workflow_error(
697
- self,
698
- target_cli: str,
699
- task: str,
700
- error_message: str
701
- ) -> str:
702
- """
703
- 格式化工作流错误结果
704
-
705
- Args:
706
- target_cli: 目标CLI工具
707
- task: 原始任务
708
- error_message: 错误信息
709
-
710
- Returns:
711
- str: 格式化的错误结果
712
- """
713
- return f"""## ❌ 跨CLI工作流失败
714
-
715
- **源工作流**: iFlow Pipeline
716
- **目标CLI**: {target_cli.upper()}
717
- **错误信息**: {error_message}
718
- **失败时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
719
-
720
- 请检查目标CLI工具是否正确安装和配置。
721
-
722
- ---
723
-
724
- *此错误由iFlow跨CLI集成系统报告*"""
725
-
726
- # ==================== 测试兼容方法 ====================
727
-
728
- def _detect_cross_cli_intent(self, context: WorkflowContext) -> bool:
729
- """
730
- 检测跨CLI调用意图(测试兼容方法)
731
-
732
- Args:
733
- context: 工作流上下文
734
-
735
- Returns:
736
- bool: 是否为跨CLI调用
737
- """
738
- try:
739
- user_input = context.data.get('prompt', context.data.get('task', ''))
740
- if not user_input:
741
- return False
742
-
743
- intent = self.parser.parse_intent(user_input, "iflow")
744
- return intent.is_cross_cli
745
-
746
- except Exception:
747
- return False
748
-
749
- def _parse_cross_cli_task(self, context: WorkflowContext) -> tuple:
750
- """
751
- 解析跨CLI任务(测试兼容方法)
752
-
753
- Args:
754
- context: 工作流上下文
755
-
756
- Returns:
757
- tuple: (target_cli, task)
758
- """
759
- try:
760
- user_input = context.data.get('prompt', context.data.get('task', ''))
761
- if not user_input:
762
- return None, None
763
-
764
- intent = self.parser.parse_intent(user_input, "iflow")
765
- if intent.is_cross_cli:
766
- return intent.target_cli, intent.task
767
-
768
- return None, None
769
-
770
- except Exception:
771
- return None, None
772
-
773
- async def _execute_cross_cli_workflow_call(
774
- self,
775
- target_cli: str,
776
- task: str,
777
- context: WorkflowContext
778
- ) -> str:
779
- """
780
- 执行跨CLI工作流调用(测试兼容方法)
781
-
782
- Args:
783
- target_cli: 目标CLI工具
784
- task: 要执行的任务
785
- context: 工作流上下文
786
-
787
- Returns:
788
- str: 执行结果
789
- """
790
- result = await self._execute_cross_cli_workflow(target_cli, task, context)
791
- if result:
792
- return result
793
- return f"跨CLI工作流调用失败: {target_cli} -> {task}"