aiforge-engine 0.0.1__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.
Files changed (153) hide show
  1. aiforge/__init__.py +64 -0
  2. aiforge/adapters/__init__.py +5 -0
  3. aiforge/adapters/input/__init__.py +0 -0
  4. aiforge/adapters/input/cli_input_adapter.py +45 -0
  5. aiforge/adapters/input/gui_input_adapter.py +40 -0
  6. aiforge/adapters/input/input_adapter.py +67 -0
  7. aiforge/adapters/input/input_adapter_manager.py +101 -0
  8. aiforge/adapters/input/input_processors.py +48 -0
  9. aiforge/adapters/input/mobile_input_adapter.py +48 -0
  10. aiforge/adapters/input/voice_input_adapter.py +44 -0
  11. aiforge/adapters/input/web_input_adapter.py +48 -0
  12. aiforge/adapters/output/__init__.py +5 -0
  13. aiforge/adapters/output/ai_ui_adapter.py +120 -0
  14. aiforge/adapters/output/enhanced_hybrid_adapter.py +82 -0
  15. aiforge/adapters/output/learning_Interface.py +190 -0
  16. aiforge/adapters/output/rule_based_adapter.py +464 -0
  17. aiforge/adapters/output/task_type_detector.py +143 -0
  18. aiforge/adapters/output/ui_type_recommender.py +72 -0
  19. aiforge/api/__init__.py +0 -0
  20. aiforge/api/middleware/auth.py +0 -0
  21. aiforge/api/middleware/rate_limit.py +0 -0
  22. aiforge/api/routes/execution.py +0 -0
  23. aiforge/api/routes/llm.py +0 -0
  24. aiforge/api/routes/tasks.py +0 -0
  25. aiforge/api/server.py +0 -0
  26. aiforge/cache/__init__.py +3 -0
  27. aiforge/cache/action_matcher.py +318 -0
  28. aiforge/cache/code_cache.py +369 -0
  29. aiforge/cache/dynamic_task_type_manager.py +143 -0
  30. aiforge/cache/semantic_cache.py +839 -0
  31. aiforge/cli/__init__.py +0 -0
  32. aiforge/cli/cli.py +87 -0
  33. aiforge/cli/commands/manager.py +73 -0
  34. aiforge/cli/wizard.py +116 -0
  35. aiforge/config/__init__.py +3 -0
  36. aiforge/config/config.py +185 -0
  37. aiforge/config/config_sync.py +0 -0
  38. aiforge/config/default.toml +97 -0
  39. aiforge/config/extension_config.py +46 -0
  40. aiforge/config/extensions.toml +45 -0
  41. aiforge/config/remote_config.py +20 -0
  42. aiforge/core/__init__.py +9 -0
  43. aiforge/core/engine.py +149 -0
  44. aiforge/core/helpers/__init__.py +3 -0
  45. aiforge/core/helpers/cache_helper.py +53 -0
  46. aiforge/core/managers/__init__.py +4 -0
  47. aiforge/core/managers/config_manager.py +75 -0
  48. aiforge/core/managers/execution_manager.py +530 -0
  49. aiforge/core/managers/search_manager.py +402 -0
  50. aiforge/core/orchestrator.py +301 -0
  51. aiforge/core/prompt.py +345 -0
  52. aiforge/core/runner.py +154 -0
  53. aiforge/core/task/__init__.py +5 -0
  54. aiforge/core/task/executor.py +271 -0
  55. aiforge/core/task/manager.py +62 -0
  56. aiforge/core/task/task.py +147 -0
  57. aiforge/deployment/__init__.py +0 -0
  58. aiforge/deployment/cloud/aws_deploy.py +0 -0
  59. aiforge/deployment/cloud/azure_deploy.py +0 -0
  60. aiforge/deployment/docker/Dockerfile +0 -0
  61. aiforge/deployment/docker/docker-compose.yml +0 -0
  62. aiforge/deployment/kubernetes/deployment.yaml +0 -0
  63. aiforge/deployment/kubernetes/service.yaml +0 -0
  64. aiforge/enterprise/__init__.py +0 -0
  65. aiforge/enterprise/audit/audit_logger.py +0 -0
  66. aiforge/enterprise/audit/compliance_checker.py +0 -0
  67. aiforge/enterprise/auth/permission_manager.py +0 -0
  68. aiforge/enterprise/auth/user_manager.py +0 -0
  69. aiforge/enterprise/monitoring/alert_manager.py +0 -0
  70. aiforge/enterprise/monitoring/metrics_collector.py +0 -0
  71. aiforge/execution/__init__.py +16 -0
  72. aiforge/execution/analyzer.py +297 -0
  73. aiforge/execution/code_blocks.py +88 -0
  74. aiforge/execution/engine.py +667 -0
  75. aiforge/execution/executor_interface.py +16 -0
  76. aiforge/execution/result_formatter.py +81 -0
  77. aiforge/execution/result_processor.py +289 -0
  78. aiforge/execution/runtimes/__init__.py +0 -0
  79. aiforge/execution/runtimes/javascript_runtime.py +0 -0
  80. aiforge/execution/runtimes/python_runtime.py +0 -0
  81. aiforge/execution/runtimes/shell_runtime.py +0 -0
  82. aiforge/execution/unified_executor.py +28 -0
  83. aiforge/extensions/__init__.py +0 -0
  84. aiforge/extensions/extension_manager.py +48 -0
  85. aiforge/extensions/loader.py +115 -0
  86. aiforge/extensions/marketplace.py +23 -0
  87. aiforge/extensions/plugin_installer.py +0 -0
  88. aiforge/extensions/template_extension.py +90 -0
  89. aiforge/instruction/__init__.py +11 -0
  90. aiforge/instruction/analyzer.py +539 -0
  91. aiforge/instruction/classifier.py +268 -0
  92. aiforge/instruction/extractor.py +253 -0
  93. aiforge/instruction/parser.py +47 -0
  94. aiforge/llm/__init__.py +8 -0
  95. aiforge/llm/conversation_manager.py +115 -0
  96. aiforge/llm/llm_client.py +240 -0
  97. aiforge/llm/llm_manager.py +150 -0
  98. aiforge/llm/providers/__init__.py +0 -0
  99. aiforge/llm/providers/deepseek_client.py +0 -0
  100. aiforge/llm/providers/ollama_client.py +0 -0
  101. aiforge/llm/providers/openai_client.py +0 -0
  102. aiforge/models/__init__.py +0 -0
  103. aiforge/models/model_manager.py +141 -0
  104. aiforge/multimodal/__init__.py +0 -0
  105. aiforge/multimodal/audio/speech_to_text.py +0 -0
  106. aiforge/multimodal/audio/text_to_speech.py +0 -0
  107. aiforge/multimodal/document/pdf_parser.py +0 -0
  108. aiforge/multimodal/document/word_parser.py +0 -0
  109. aiforge/multimodal/vision/image_processor.py +0 -0
  110. aiforge/multimodal/vision/video_processor.py +0 -0
  111. aiforge/optimization/code_optimizer.py +163 -0
  112. aiforge/optimization/feedback_optimizer.py +42 -0
  113. aiforge/plugins/__init__.py +0 -0
  114. aiforge/plugins/builtin/data_analysis.py +0 -0
  115. aiforge/plugins/builtin/file_processing.py +0 -0
  116. aiforge/plugins/builtin/web_scraping.py +0 -0
  117. aiforge/plugins/plugin_interface.py +0 -0
  118. aiforge/plugins/plugin_manager.py +0 -0
  119. aiforge/strategies/__init__.py +41 -0
  120. aiforge/strategies/execution_strategy.py +106 -0
  121. aiforge/strategies/execution_strategy_manager.py +44 -0
  122. aiforge/strategies/parameter_mapping_service.py +895 -0
  123. aiforge/strategies/search_template_strategy.py +108 -0
  124. aiforge/strategies/semantic_field_strategy.py +257 -0
  125. aiforge/strategies/strategy/__init__.py +0 -0
  126. aiforge/strategies/strategy/class_instantiation.py +68 -0
  127. aiforge/strategies/strategy/direct_result.py +33 -0
  128. aiforge/strategies/strategy/file_operation.py +832 -0
  129. aiforge/strategies/strategy/file_operation_safety.py +317 -0
  130. aiforge/strategies/strategy/parameterized_function.py +168 -0
  131. aiforge/strategies/validation_strategy.py +125 -0
  132. aiforge/templates/__init__.py +9 -0
  133. aiforge/templates/builtin/automation.json +0 -0
  134. aiforge/templates/builtin/data_analysis.json +0 -0
  135. aiforge/templates/builtin/web_api.json +0 -0
  136. aiforge/templates/search_template.py +1311 -0
  137. aiforge/templates/template_manager.py +331 -0
  138. aiforge/utils/__init__.py +0 -0
  139. aiforge/utils/helpers.py +0 -0
  140. aiforge/utils/sentence_transformers_downloader.py +44 -0
  141. aiforge/utils/utils.py +290 -0
  142. aiforge/validation/code_validator.py +33 -0
  143. aiforge/validation/result_validator.py +260 -0
  144. aiforge/workflow/__init__.py +0 -0
  145. aiforge/workflow/nodes/data_node.py +0 -0
  146. aiforge/workflow/nodes/execution_node.py +0 -0
  147. aiforge/workflow/nodes/llm_node.py +0 -0
  148. aiforge/workflow/workflow_designer.py +0 -0
  149. aiforge/workflow/workflow_engine.py +0 -0
  150. aiforge_engine-0.0.1.dist-info/METADATA +11 -0
  151. aiforge_engine-0.0.1.dist-info/RECORD +153 -0
  152. aiforge_engine-0.0.1.dist-info/WHEEL +4 -0
  153. aiforge_engine-0.0.1.dist-info/licenses/LICENSE +201 -0
aiforge/__init__.py ADDED
@@ -0,0 +1,64 @@
1
+ # 核心模块导入
2
+ from .core.engine import AIForgeEngine
3
+ from .core.task.manager import AIForgeTaskManager
4
+ from .core.task.task import AIForgeTask
5
+ from .execution.result_processor import AIForgeResultProcessor
6
+
7
+ # LLM模块导入
8
+ from .llm.llm_client import AIForgeLLMClient, AIForgeOllamaClient
9
+ from .llm.llm_manager import AIForgeLLMManager
10
+
11
+ # 执行引擎导入
12
+ from .execution.engine import AIForgeExecutionEngine
13
+
14
+ # 配置管理导入
15
+ from .config.config import AIForgeConfig
16
+
17
+ # 数据获取相关导入
18
+ from .templates.template_manager import TemplateManager
19
+ from .strategies.search_template_strategy import (
20
+ StandardTemplateStrategy,
21
+ TemplateGenerationStrategy,
22
+ )
23
+ from .strategies.semantic_field_strategy import SemanticFieldStrategy, FieldProcessorManager
24
+
25
+ # 其他相关导入
26
+ from .execution.result_formatter import AIForgeResultFormatter
27
+ from .execution.code_blocks import CodeBlockManager, CodeBlock
28
+ from .core.prompt import AIForgePrompt
29
+ from .cli.wizard import create_config_wizard
30
+ from .cache.semantic_cache import EnhancedStandardizedCache
31
+
32
+ # 指令分析导入
33
+ from .instruction.analyzer import AIForgeInstructionAnalyzer
34
+
35
+ __all__ = [
36
+ # 核心组件
37
+ "AIForgeEngine",
38
+ "AIForgeTaskManager",
39
+ "AIForgeTask",
40
+ "AIForgeResultProcessor",
41
+ "AIForgeConfig",
42
+ # LLM组件
43
+ "AIForgeLLMClient",
44
+ "AIForgeOllamaClient",
45
+ "AIForgeLLMManager",
46
+ # 执行组件
47
+ "AIForgeExecutionEngine",
48
+ "EnhancedStandardizedCache",
49
+ # 数据获取组件
50
+ "TemplateManager",
51
+ "StandardTemplateStrategy",
52
+ "TemplateGenerationStrategy",
53
+ "SemanticFieldStrategy",
54
+ "FieldProcessorManager",
55
+ "AIForgeInstructionAnalyzer",
56
+ # 工具组件
57
+ "create_config_wizard",
58
+ "AIForgeResultFormatter",
59
+ "CodeBlockManager",
60
+ "CodeBlock",
61
+ "AIForgePrompt",
62
+ ]
63
+
64
+ __version__ = "0.0.1"
@@ -0,0 +1,5 @@
1
+ from .output.rule_based_adapter import RuleBasedAdapter
2
+ from .output.ui_type_recommender import UITypeRecommender
3
+ from .output.task_type_detector import TaskTypeDetector
4
+
5
+ __all__ = ["RuleBasedAdapter", "UITypeRecommender", "TaskTypeDetector"]
File without changes
@@ -0,0 +1,45 @@
1
+ from typing import Any
2
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
3
+
4
+
5
+ class CLIInputAdapter(InputAdapter):
6
+ """CLI输入适配器"""
7
+
8
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
9
+ return source == InputSource.CLI and isinstance(raw_input, (str, dict))
10
+
11
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
12
+ """适配CLI输入"""
13
+ if isinstance(raw_input, str):
14
+ # 简单字符串指令
15
+ instruction = raw_input
16
+ metadata = {"input_type": "simple_command"}
17
+ elif isinstance(raw_input, dict):
18
+ # 结构化CLI参数
19
+ instruction = raw_input.get("instruction", "")
20
+ metadata = {
21
+ "input_type": "structured_command",
22
+ "args": raw_input.get("args", {}),
23
+ "flags": raw_input.get("flags", {}),
24
+ "options": raw_input.get("options", {}),
25
+ }
26
+ else:
27
+ raise ValueError(f"Unsupported CLI input type: {type(raw_input)}")
28
+
29
+ # CLI特定的元数据
30
+ metadata.update(
31
+ {
32
+ "terminal_width": context.device_info.get("terminal_width", 80),
33
+ "supports_color": context.device_info.get("supports_color", True),
34
+ "shell_type": context.device_info.get("shell", "bash"),
35
+ }
36
+ )
37
+
38
+ return StandardizedInput(instruction=instruction, context=context, metadata=metadata)
39
+
40
+ def validate(self, standardized_input: StandardizedInput) -> bool:
41
+ """验证CLI输入"""
42
+ return (
43
+ bool(standardized_input.instruction.strip())
44
+ and len(standardized_input.instruction) <= 10000 # CLI输入长度限制
45
+ )
@@ -0,0 +1,40 @@
1
+ from typing import Any
2
+
3
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
4
+
5
+
6
+ class GUIInputAdapter(InputAdapter):
7
+ """GUI输入适配器"""
8
+
9
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
10
+ return source == InputSource.GUI and isinstance(raw_input, dict)
11
+
12
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
13
+ """适配GUI输入"""
14
+ instruction = raw_input.get("text", "")
15
+
16
+ # GUI特定的元数据
17
+ metadata = {
18
+ "input_type": "gui_text",
19
+ "widget_id": raw_input.get("widget_id"),
20
+ "cursor_position": raw_input.get("cursor_position", 0),
21
+ "selection": raw_input.get("selection", {}),
22
+ "input_method": raw_input.get("input_method", "keyboard"),
23
+ "screen_size": context.device_info.get("screen_size", {}),
24
+ "theme": context.preferences.get("theme", "default"),
25
+ }
26
+
27
+ # 处理附件(如果有)
28
+ attachments = {}
29
+ if "files" in raw_input:
30
+ attachments["files"] = raw_input["files"]
31
+ if "images" in raw_input:
32
+ attachments["images"] = raw_input["images"]
33
+
34
+ return StandardizedInput(
35
+ instruction=instruction, context=context, metadata=metadata, attachments=attachments
36
+ )
37
+
38
+ def validate(self, standardized_input: StandardizedInput) -> bool:
39
+ """验证GUI输入"""
40
+ return bool(standardized_input.instruction.strip())
@@ -0,0 +1,67 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Dict, Any, Optional
3
+ from enum import Enum
4
+
5
+
6
+ class InputSource(Enum):
7
+ """输入源类型"""
8
+
9
+ CLI = "cli"
10
+ GUI = "gui"
11
+ WEB = "web"
12
+ MOBILE = "mobile"
13
+ API = "api"
14
+ VOICE = "voice"
15
+
16
+
17
+ class InputContext:
18
+ """输入上下文信息"""
19
+
20
+ def __init__(
21
+ self,
22
+ source: InputSource,
23
+ user_id: Optional[str] = None,
24
+ session_id: Optional[str] = None,
25
+ device_info: Optional[Dict[str, Any]] = None,
26
+ preferences: Optional[Dict[str, Any]] = None,
27
+ ):
28
+ self.source = source
29
+ self.user_id = user_id
30
+ self.session_id = session_id
31
+ self.device_info = device_info or {}
32
+ self.preferences = preferences or {}
33
+
34
+
35
+ class StandardizedInput:
36
+ """标准化输入结构"""
37
+
38
+ def __init__(
39
+ self,
40
+ instruction: str,
41
+ context: InputContext,
42
+ metadata: Optional[Dict[str, Any]] = None,
43
+ attachments: Optional[Dict[str, Any]] = None,
44
+ ):
45
+ self.instruction = instruction
46
+ self.context = context
47
+ self.metadata = metadata or {}
48
+ self.attachments = attachments or {}
49
+
50
+
51
+ class InputAdapter(ABC):
52
+ """输入适配器基类"""
53
+
54
+ @abstractmethod
55
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
56
+ """检查是否能处理特定类型的输入"""
57
+ pass
58
+
59
+ @abstractmethod
60
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
61
+ """将原始输入适配为标准化输入"""
62
+ pass
63
+
64
+ @abstractmethod
65
+ def validate(self, standardized_input: StandardizedInput) -> bool:
66
+ """验证标准化输入的有效性"""
67
+ pass
@@ -0,0 +1,101 @@
1
+ from typing import List, Dict, Any, Optional
2
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
3
+ from .cli_input_adapter import CLIInputAdapter
4
+ from .gui_input_adapter import GUIInputAdapter
5
+ from .web_input_adapter import WebInputAdapter
6
+ from .mobile_input_adapter import MobileInputAdapter
7
+ from .voice_input_adapter import VoiceInputAdapter
8
+
9
+
10
+ class InputAdapterManager:
11
+ """输入适配管理器"""
12
+
13
+ def __init__(self):
14
+ self.adapters: List[InputAdapter] = [
15
+ CLIInputAdapter(),
16
+ GUIInputAdapter(),
17
+ WebInputAdapter(),
18
+ MobileInputAdapter(),
19
+ VoiceInputAdapter(),
20
+ ]
21
+
22
+ # 输入预处理器
23
+ self.preprocessors = []
24
+
25
+ # 输入后处理器
26
+ self.postprocessors = []
27
+
28
+ def register_adapter(self, adapter: InputAdapter):
29
+ """注册自定义适配器"""
30
+ self.adapters.append(adapter)
31
+
32
+ def adapt_input(
33
+ self, raw_input: Any, source: InputSource, context_data: Optional[Dict[str, Any]] = None
34
+ ) -> StandardizedInput:
35
+ """适配输入"""
36
+ # 创建输入上下文
37
+ context = self._create_context(source, context_data or {})
38
+
39
+ # 预处理
40
+ processed_input = self._preprocess(raw_input, context)
41
+
42
+ # 找到合适的适配器
43
+ adapter = self._find_adapter(processed_input, source)
44
+ if not adapter:
45
+ raise ValueError(f"No adapter found for source: {source}")
46
+
47
+ # 执行适配
48
+ standardized_input = adapter.adapt(processed_input, context)
49
+
50
+ # 验证
51
+ if not adapter.validate(standardized_input):
52
+ raise ValueError("Input validation failed")
53
+
54
+ # 后处理
55
+ final_input = self._postprocess(standardized_input)
56
+
57
+ return final_input
58
+
59
+ def _create_context(self, source: InputSource, context_data: Dict[str, Any]) -> InputContext:
60
+ """创建输入上下文"""
61
+ return InputContext(
62
+ source=source,
63
+ user_id=context_data.get("user_id"),
64
+ session_id=context_data.get("session_id"),
65
+ device_info=context_data.get("device_info", {}),
66
+ preferences=context_data.get("preferences", {}),
67
+ )
68
+
69
+ def _find_adapter(self, raw_input: Any, source: InputSource) -> Optional[InputAdapter]:
70
+ """找到合适的适配器"""
71
+ for adapter in self.adapters:
72
+ if adapter.can_handle(raw_input, source):
73
+ return adapter
74
+ return None
75
+
76
+ def _preprocess(self, raw_input: Any, context: InputContext) -> Any:
77
+ """预处理输入"""
78
+ processed = raw_input
79
+ for preprocessor in self.preprocessors:
80
+ processed = preprocessor.process(processed, context)
81
+ return processed
82
+
83
+ def _postprocess(self, standardized_input: StandardizedInput) -> StandardizedInput:
84
+ """后处理标准化输入"""
85
+ processed = standardized_input
86
+ for postprocessor in self.postprocessors:
87
+ processed = postprocessor.process(processed)
88
+ return processed
89
+
90
+ def get_supported_sources(self) -> List[InputSource]:
91
+ """获取支持的输入源"""
92
+ return list(InputSource)
93
+
94
+ def get_adapter_stats(self) -> Dict[str, Any]:
95
+ """获取适配器统计信息"""
96
+ return {
97
+ "total_adapters": len(self.adapters),
98
+ "supported_sources": [source.value for source in self.get_supported_sources()],
99
+ "preprocessors": len(self.preprocessors),
100
+ "postprocessors": len(self.postprocessors),
101
+ }
@@ -0,0 +1,48 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any
3
+ from .input_adapter import InputContext, StandardizedInput
4
+
5
+
6
+ class InputPreprocessor(ABC):
7
+ """输入预处理器基类"""
8
+
9
+ @abstractmethod
10
+ def process(self, raw_input: Any, context: InputContext) -> Any:
11
+ pass
12
+
13
+
14
+ class InputPostprocessor(ABC):
15
+ """输入后处理器基类"""
16
+
17
+ @abstractmethod
18
+ def process(self, standardized_input: StandardizedInput) -> StandardizedInput:
19
+ pass
20
+
21
+
22
+ class TextCleanupPreprocessor(InputPreprocessor):
23
+ """文本清理预处理器"""
24
+
25
+ def process(self, raw_input: Any, context: InputContext) -> Any:
26
+ if isinstance(raw_input, str):
27
+ # 清理多余空白字符
28
+ return raw_input.strip()
29
+ elif isinstance(raw_input, dict) and "text" in raw_input:
30
+ raw_input["text"] = raw_input["text"].strip()
31
+ return raw_input
32
+
33
+
34
+ class SecurityValidationPostprocessor(InputPostprocessor):
35
+ """安全验证后处理器"""
36
+
37
+ def process(self, standardized_input: StandardizedInput) -> StandardizedInput:
38
+ # 检查指令长度
39
+ if len(standardized_input.instruction) > 100000:
40
+ raise ValueError("Instruction too long")
41
+
42
+ # 检查恶意内容(简单示例)
43
+ dangerous_patterns = ["rm -rf", "del /", "format c:"]
44
+ for pattern in dangerous_patterns:
45
+ if pattern.lower() in standardized_input.instruction.lower():
46
+ raise ValueError(f"Potentially dangerous instruction detected: {pattern}")
47
+
48
+ return standardized_input
@@ -0,0 +1,48 @@
1
+ from typing import Any
2
+
3
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
4
+
5
+
6
+ class MobileInputAdapter(InputAdapter):
7
+ """移动端输入适配器"""
8
+
9
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
10
+ return source == InputSource.MOBILE and isinstance(raw_input, dict)
11
+
12
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
13
+ """适配移动端输入"""
14
+ instruction = raw_input.get("text", "")
15
+
16
+ # 移动端特定的元数据
17
+ metadata = {
18
+ "input_type": "mobile_input",
19
+ "input_method": raw_input.get("input_method", "touch"), # touch, voice, gesture
20
+ "orientation": context.device_info.get("orientation", "portrait"),
21
+ "device_type": context.device_info.get("device_type", "phone"), # phone, tablet
22
+ "os": context.device_info.get("os", "unknown"),
23
+ "app_version": context.device_info.get("app_version", ""),
24
+ "network_type": context.device_info.get("network", "wifi"),
25
+ "battery_level": context.device_info.get("battery", 100),
26
+ "location": raw_input.get("location", {}) if raw_input.get("location_enabled") else {},
27
+ }
28
+
29
+ # 处理移动端特有的输入
30
+ attachments = {}
31
+ if "photos" in raw_input:
32
+ attachments["photos"] = raw_input["photos"]
33
+ if "voice_recording" in raw_input:
34
+ attachments["voice"] = raw_input["voice_recording"]
35
+ if "camera_capture" in raw_input:
36
+ attachments["camera"] = raw_input["camera_capture"]
37
+
38
+ return StandardizedInput(
39
+ instruction=instruction, context=context, metadata=metadata, attachments=attachments
40
+ )
41
+
42
+ def validate(self, standardized_input: StandardizedInput) -> bool:
43
+ """验证移动端输入"""
44
+ # 移动端输入可能更简短
45
+ return (
46
+ bool(standardized_input.instruction.strip())
47
+ and len(standardized_input.instruction) <= 5000
48
+ )
@@ -0,0 +1,44 @@
1
+ from typing import Any
2
+
3
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
4
+
5
+
6
+ class VoiceInputAdapter(InputAdapter):
7
+ """语音输入适配器"""
8
+
9
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
10
+ return source == InputSource.VOICE and isinstance(raw_input, dict)
11
+
12
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
13
+ """适配语音输入"""
14
+ # 语音转文字后的指令
15
+ instruction = raw_input.get("transcribed_text", "")
16
+
17
+ # 语音特定的元数据
18
+ metadata = {
19
+ "input_type": "voice_input",
20
+ "audio_format": raw_input.get("audio_format", "wav"),
21
+ "sample_rate": raw_input.get("sample_rate", 16000),
22
+ "duration": raw_input.get("duration", 0),
23
+ "confidence_score": raw_input.get("confidence", 0.0),
24
+ "language": raw_input.get("detected_language", "zh-CN"),
25
+ "speaker_id": raw_input.get("speaker_id"),
26
+ "noise_level": raw_input.get("noise_level", "low"),
27
+ "transcription_engine": raw_input.get("engine", "default"),
28
+ }
29
+
30
+ # 保存原始音频数据
31
+ attachments = {}
32
+ if "audio_data" in raw_input:
33
+ attachments["audio"] = raw_input["audio_data"]
34
+
35
+ return StandardizedInput(
36
+ instruction=instruction, context=context, metadata=metadata, attachments=attachments
37
+ )
38
+
39
+ def validate(self, standardized_input: StandardizedInput) -> bool:
40
+ """验证语音输入"""
41
+ confidence = standardized_input.metadata.get("confidence_score", 0.0)
42
+ return (
43
+ bool(standardized_input.instruction.strip()) and confidence >= 0.6 # 语音识别置信度阈值
44
+ )
@@ -0,0 +1,48 @@
1
+ from typing import Any
2
+
3
+ from .input_adapter import InputAdapter, InputSource, InputContext, StandardizedInput
4
+
5
+
6
+ class WebInputAdapter(InputAdapter):
7
+ """Web输入适配器"""
8
+
9
+ def can_handle(self, raw_input: Any, source: InputSource) -> bool:
10
+ return source == InputSource.WEB and isinstance(raw_input, dict)
11
+
12
+ def adapt(self, raw_input: Any, context: InputContext) -> StandardizedInput:
13
+ """适配Web输入"""
14
+ instruction = raw_input.get("instruction", "")
15
+
16
+ # Web特定的元数据
17
+ metadata = {
18
+ "input_type": "web_request",
19
+ "http_method": raw_input.get("method", "POST"),
20
+ "user_agent": raw_input.get("user_agent", ""),
21
+ "ip_address": raw_input.get("ip_address", ""),
22
+ "referrer": raw_input.get("referrer", ""),
23
+ "browser_info": context.device_info.get("browser", {}),
24
+ "viewport": context.device_info.get("viewport", {}),
25
+ "request_id": raw_input.get("request_id"),
26
+ }
27
+
28
+ # 处理Web特有的参数
29
+ if "form_data" in raw_input:
30
+ metadata["form_data"] = raw_input["form_data"]
31
+ if "query_params" in raw_input:
32
+ metadata["query_params"] = raw_input["query_params"]
33
+
34
+ # 处理文件上传
35
+ attachments = {}
36
+ if "uploaded_files" in raw_input:
37
+ attachments["files"] = raw_input["uploaded_files"]
38
+
39
+ return StandardizedInput(
40
+ instruction=instruction, context=context, metadata=metadata, attachments=attachments
41
+ )
42
+
43
+ def validate(self, standardized_input: StandardizedInput) -> bool:
44
+ """验证Web输入"""
45
+ return (
46
+ bool(standardized_input.instruction.strip())
47
+ and len(standardized_input.instruction) <= 50000 # Web输入可以更长
48
+ )
@@ -0,0 +1,5 @@
1
+ from .rule_based_adapter import RuleBasedAdapter
2
+ from .ui_type_recommender import UITypeRecommender
3
+ from .task_type_detector import TaskTypeDetector
4
+
5
+ __all__ = ["RuleBasedAdapter", "UITypeRecommender", "TaskTypeDetector"]
@@ -0,0 +1,120 @@
1
+ import json
2
+ import hashlib
3
+ from typing import Dict, Any
4
+ from ...llm.llm_client import AIForgeLLMClient
5
+
6
+
7
+ class AIUIAdapter:
8
+ """AI驱动的UI适配器"""
9
+
10
+ def __init__(self, llm_client: AIForgeLLMClient):
11
+ self.llm_client = llm_client
12
+ self.cache = {} # 简单的内存缓存
13
+
14
+ def adapt_for_display(self, data: Dict[str, Any], ui_context: str) -> Dict[str, Any]:
15
+ """根据UI上下文需求,让AI分析并转换数据格式"""
16
+ # 生成缓存键
17
+ cache_key = self._generate_cache_key(data, ui_context)
18
+
19
+ # 检查缓存
20
+ if cache_key in self.cache:
21
+ return self.cache[cache_key]
22
+
23
+ # AI分析
24
+ prompt = self._build_adaptation_prompt(data, ui_context)
25
+
26
+ try:
27
+ response = self.llm_client.generate_code(prompt, "")
28
+ adapted_result = self._parse_adaptation_result(response)
29
+
30
+ # 缓存结果
31
+ self.cache[cache_key] = adapted_result
32
+
33
+ return adapted_result
34
+ except Exception:
35
+ # 失败时返回基础格式
36
+ return self._create_fallback_format(data, ui_context)
37
+
38
+ def _build_adaptation_prompt(self, data: Dict[str, Any], ui_context: str) -> str:
39
+ """构建适配提示词"""
40
+ return f"""
41
+ # 任务:数据格式适配
42
+ 你需要将原始数据转换为适合特定界面展示的格式。
43
+
44
+ ## 原始数据
45
+ {json.dumps(data, ensure_ascii=False, indent=2)}
46
+
47
+ ## 目标界面类型
48
+ {ui_context}
49
+
50
+ ## 输出要求
51
+ 请返回以下JSON格式:
52
+ {{
53
+ "display_items": [
54
+ {{
55
+ "type": "text|table|card|list|chart",
56
+ "title": "显示标题",
57
+ "content": "具体内容",
58
+ "priority": 1-10
59
+ }}
60
+ ],
61
+ "layout_hints": {{
62
+ "layout_type": "vertical|horizontal|grid",
63
+ "columns": 1-4,
64
+ "spacing": "compact|normal|loose"
65
+ }},
66
+ "actions": [
67
+ {{
68
+ "label": "操作名称",
69
+ "action": "refresh|export|detail",
70
+ "data": {{}}
71
+ }}
72
+ ],
73
+ "summary_text": "数据摘要文本"
74
+ }}
75
+
76
+ 请严格按照JSON格式返回,不要包含其他解释文字。
77
+ """
78
+
79
+ def _parse_adaptation_result(self, response: str) -> Dict[str, Any]:
80
+ """解析AI适配结果"""
81
+ # 提取JSON内容
82
+ import re
83
+
84
+ json_match = re.search(r"\{.*\}", response, re.DOTALL)
85
+ if json_match:
86
+ try:
87
+ return json.loads(json_match.group(0))
88
+ except json.JSONDecodeError:
89
+ pass
90
+
91
+ # 解析失败时返回默认结构
92
+ return {
93
+ "display_items": [
94
+ {"type": "text", "title": "数据", "content": str(response)[:200], "priority": 5}
95
+ ],
96
+ "layout_hints": {"layout_type": "vertical", "columns": 1, "spacing": "normal"},
97
+ "actions": [],
98
+ "summary_text": "AI适配解析失败",
99
+ }
100
+
101
+ def _generate_cache_key(self, data: Dict[str, Any], ui_context: str) -> str:
102
+ """生成缓存键"""
103
+ content = f"{json.dumps(data, sort_keys=True)}_{ui_context}"
104
+ return hashlib.md5(content.encode()).hexdigest()[:16]
105
+
106
+ def _create_fallback_format(self, data: Dict[str, Any], ui_context: str) -> Dict[str, Any]:
107
+ """创建回退格式"""
108
+ return {
109
+ "display_items": [
110
+ {
111
+ "type": "text",
112
+ "title": "原始数据",
113
+ "content": json.dumps(data, ensure_ascii=False, indent=2),
114
+ "priority": 5,
115
+ }
116
+ ],
117
+ "layout_hints": {"layout_type": "vertical", "columns": 1, "spacing": "normal"},
118
+ "actions": [{"label": "刷新", "action": "refresh", "data": {}}],
119
+ "summary_text": f"显示原始数据 ({ui_context})",
120
+ }