aiecs 1.5.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 (302) hide show
  1. aiecs/__init__.py +72 -0
  2. aiecs/__main__.py +41 -0
  3. aiecs/aiecs_client.py +469 -0
  4. aiecs/application/__init__.py +10 -0
  5. aiecs/application/executors/__init__.py +10 -0
  6. aiecs/application/executors/operation_executor.py +363 -0
  7. aiecs/application/knowledge_graph/__init__.py +7 -0
  8. aiecs/application/knowledge_graph/builder/__init__.py +37 -0
  9. aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
  10. aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
  11. aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
  12. aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
  13. aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
  14. aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
  15. aiecs/application/knowledge_graph/extractors/base.py +100 -0
  16. aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
  17. aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
  18. aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
  19. aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
  20. aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
  21. aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
  22. aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
  23. aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
  24. aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
  25. aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
  26. aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
  27. aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
  28. aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
  29. aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
  30. aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
  31. aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
  32. aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
  33. aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
  34. aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
  35. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
  36. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
  37. aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
  38. aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
  39. aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
  40. aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
  41. aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
  42. aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
  43. aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
  44. aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
  45. aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
  46. aiecs/application/knowledge_graph/search/__init__.py +59 -0
  47. aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
  48. aiecs/application/knowledge_graph/search/reranker.py +295 -0
  49. aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
  50. aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
  51. aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
  52. aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
  53. aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
  54. aiecs/application/knowledge_graph/validators/__init__.py +13 -0
  55. aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
  56. aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
  57. aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
  58. aiecs/common/__init__.py +9 -0
  59. aiecs/common/knowledge_graph/__init__.py +17 -0
  60. aiecs/common/knowledge_graph/runnable.py +484 -0
  61. aiecs/config/__init__.py +16 -0
  62. aiecs/config/config.py +498 -0
  63. aiecs/config/graph_config.py +137 -0
  64. aiecs/config/registry.py +23 -0
  65. aiecs/core/__init__.py +46 -0
  66. aiecs/core/interface/__init__.py +34 -0
  67. aiecs/core/interface/execution_interface.py +152 -0
  68. aiecs/core/interface/storage_interface.py +171 -0
  69. aiecs/domain/__init__.py +289 -0
  70. aiecs/domain/agent/__init__.py +189 -0
  71. aiecs/domain/agent/base_agent.py +697 -0
  72. aiecs/domain/agent/exceptions.py +103 -0
  73. aiecs/domain/agent/graph_aware_mixin.py +559 -0
  74. aiecs/domain/agent/hybrid_agent.py +490 -0
  75. aiecs/domain/agent/integration/__init__.py +26 -0
  76. aiecs/domain/agent/integration/context_compressor.py +222 -0
  77. aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
  78. aiecs/domain/agent/integration/retry_policy.py +219 -0
  79. aiecs/domain/agent/integration/role_config.py +213 -0
  80. aiecs/domain/agent/knowledge_aware_agent.py +646 -0
  81. aiecs/domain/agent/lifecycle.py +296 -0
  82. aiecs/domain/agent/llm_agent.py +300 -0
  83. aiecs/domain/agent/memory/__init__.py +12 -0
  84. aiecs/domain/agent/memory/conversation.py +197 -0
  85. aiecs/domain/agent/migration/__init__.py +14 -0
  86. aiecs/domain/agent/migration/conversion.py +160 -0
  87. aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
  88. aiecs/domain/agent/models.py +317 -0
  89. aiecs/domain/agent/observability.py +407 -0
  90. aiecs/domain/agent/persistence.py +289 -0
  91. aiecs/domain/agent/prompts/__init__.py +29 -0
  92. aiecs/domain/agent/prompts/builder.py +161 -0
  93. aiecs/domain/agent/prompts/formatters.py +189 -0
  94. aiecs/domain/agent/prompts/template.py +255 -0
  95. aiecs/domain/agent/registry.py +260 -0
  96. aiecs/domain/agent/tool_agent.py +257 -0
  97. aiecs/domain/agent/tools/__init__.py +12 -0
  98. aiecs/domain/agent/tools/schema_generator.py +221 -0
  99. aiecs/domain/community/__init__.py +155 -0
  100. aiecs/domain/community/agent_adapter.py +477 -0
  101. aiecs/domain/community/analytics.py +481 -0
  102. aiecs/domain/community/collaborative_workflow.py +642 -0
  103. aiecs/domain/community/communication_hub.py +645 -0
  104. aiecs/domain/community/community_builder.py +320 -0
  105. aiecs/domain/community/community_integration.py +800 -0
  106. aiecs/domain/community/community_manager.py +813 -0
  107. aiecs/domain/community/decision_engine.py +879 -0
  108. aiecs/domain/community/exceptions.py +225 -0
  109. aiecs/domain/community/models/__init__.py +33 -0
  110. aiecs/domain/community/models/community_models.py +268 -0
  111. aiecs/domain/community/resource_manager.py +457 -0
  112. aiecs/domain/community/shared_context_manager.py +603 -0
  113. aiecs/domain/context/__init__.py +58 -0
  114. aiecs/domain/context/context_engine.py +989 -0
  115. aiecs/domain/context/conversation_models.py +354 -0
  116. aiecs/domain/context/graph_memory.py +467 -0
  117. aiecs/domain/execution/__init__.py +12 -0
  118. aiecs/domain/execution/model.py +57 -0
  119. aiecs/domain/knowledge_graph/__init__.py +19 -0
  120. aiecs/domain/knowledge_graph/models/__init__.py +52 -0
  121. aiecs/domain/knowledge_graph/models/entity.py +130 -0
  122. aiecs/domain/knowledge_graph/models/evidence.py +194 -0
  123. aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
  124. aiecs/domain/knowledge_graph/models/path.py +179 -0
  125. aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
  126. aiecs/domain/knowledge_graph/models/query.py +272 -0
  127. aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
  128. aiecs/domain/knowledge_graph/models/relation.py +136 -0
  129. aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
  130. aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
  131. aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
  132. aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
  133. aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
  134. aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
  135. aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
  136. aiecs/domain/task/__init__.py +13 -0
  137. aiecs/domain/task/dsl_processor.py +613 -0
  138. aiecs/domain/task/model.py +62 -0
  139. aiecs/domain/task/task_context.py +268 -0
  140. aiecs/infrastructure/__init__.py +24 -0
  141. aiecs/infrastructure/graph_storage/__init__.py +11 -0
  142. aiecs/infrastructure/graph_storage/base.py +601 -0
  143. aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
  144. aiecs/infrastructure/graph_storage/cache.py +429 -0
  145. aiecs/infrastructure/graph_storage/distributed.py +226 -0
  146. aiecs/infrastructure/graph_storage/error_handling.py +390 -0
  147. aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
  148. aiecs/infrastructure/graph_storage/health_checks.py +378 -0
  149. aiecs/infrastructure/graph_storage/in_memory.py +514 -0
  150. aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
  151. aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
  152. aiecs/infrastructure/graph_storage/metrics.py +357 -0
  153. aiecs/infrastructure/graph_storage/migration.py +413 -0
  154. aiecs/infrastructure/graph_storage/pagination.py +471 -0
  155. aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
  156. aiecs/infrastructure/graph_storage/postgres.py +871 -0
  157. aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
  158. aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
  159. aiecs/infrastructure/graph_storage/sqlite.py +623 -0
  160. aiecs/infrastructure/graph_storage/streaming.py +495 -0
  161. aiecs/infrastructure/messaging/__init__.py +13 -0
  162. aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
  163. aiecs/infrastructure/messaging/websocket_manager.py +298 -0
  164. aiecs/infrastructure/monitoring/__init__.py +34 -0
  165. aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
  166. aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
  167. aiecs/infrastructure/monitoring/structured_logger.py +48 -0
  168. aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
  169. aiecs/infrastructure/persistence/__init__.py +24 -0
  170. aiecs/infrastructure/persistence/context_engine_client.py +187 -0
  171. aiecs/infrastructure/persistence/database_manager.py +333 -0
  172. aiecs/infrastructure/persistence/file_storage.py +754 -0
  173. aiecs/infrastructure/persistence/redis_client.py +220 -0
  174. aiecs/llm/__init__.py +86 -0
  175. aiecs/llm/callbacks/__init__.py +11 -0
  176. aiecs/llm/callbacks/custom_callbacks.py +264 -0
  177. aiecs/llm/client_factory.py +420 -0
  178. aiecs/llm/clients/__init__.py +33 -0
  179. aiecs/llm/clients/base_client.py +193 -0
  180. aiecs/llm/clients/googleai_client.py +181 -0
  181. aiecs/llm/clients/openai_client.py +131 -0
  182. aiecs/llm/clients/vertex_client.py +437 -0
  183. aiecs/llm/clients/xai_client.py +184 -0
  184. aiecs/llm/config/__init__.py +51 -0
  185. aiecs/llm/config/config_loader.py +275 -0
  186. aiecs/llm/config/config_validator.py +236 -0
  187. aiecs/llm/config/model_config.py +151 -0
  188. aiecs/llm/utils/__init__.py +10 -0
  189. aiecs/llm/utils/validate_config.py +91 -0
  190. aiecs/main.py +363 -0
  191. aiecs/scripts/__init__.py +3 -0
  192. aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
  193. aiecs/scripts/aid/__init__.py +19 -0
  194. aiecs/scripts/aid/version_manager.py +215 -0
  195. aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
  196. aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
  197. aiecs/scripts/dependance_check/__init__.py +17 -0
  198. aiecs/scripts/dependance_check/dependency_checker.py +938 -0
  199. aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
  200. aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
  201. aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
  202. aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
  203. aiecs/scripts/dependance_patch/__init__.py +7 -0
  204. aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
  205. aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
  206. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
  207. aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
  208. aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
  209. aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
  210. aiecs/scripts/tools_develop/README.md +449 -0
  211. aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
  212. aiecs/scripts/tools_develop/__init__.py +21 -0
  213. aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
  214. aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
  215. aiecs/scripts/tools_develop/verify_tools.py +356 -0
  216. aiecs/tasks/__init__.py +1 -0
  217. aiecs/tasks/worker.py +172 -0
  218. aiecs/tools/__init__.py +299 -0
  219. aiecs/tools/apisource/__init__.py +99 -0
  220. aiecs/tools/apisource/intelligence/__init__.py +19 -0
  221. aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
  222. aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
  223. aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
  224. aiecs/tools/apisource/monitoring/__init__.py +9 -0
  225. aiecs/tools/apisource/monitoring/metrics.py +303 -0
  226. aiecs/tools/apisource/providers/__init__.py +115 -0
  227. aiecs/tools/apisource/providers/base.py +664 -0
  228. aiecs/tools/apisource/providers/census.py +401 -0
  229. aiecs/tools/apisource/providers/fred.py +564 -0
  230. aiecs/tools/apisource/providers/newsapi.py +412 -0
  231. aiecs/tools/apisource/providers/worldbank.py +357 -0
  232. aiecs/tools/apisource/reliability/__init__.py +12 -0
  233. aiecs/tools/apisource/reliability/error_handler.py +375 -0
  234. aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
  235. aiecs/tools/apisource/tool.py +850 -0
  236. aiecs/tools/apisource/utils/__init__.py +9 -0
  237. aiecs/tools/apisource/utils/validators.py +338 -0
  238. aiecs/tools/base_tool.py +201 -0
  239. aiecs/tools/docs/__init__.py +121 -0
  240. aiecs/tools/docs/ai_document_orchestrator.py +599 -0
  241. aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
  242. aiecs/tools/docs/content_insertion_tool.py +1333 -0
  243. aiecs/tools/docs/document_creator_tool.py +1317 -0
  244. aiecs/tools/docs/document_layout_tool.py +1166 -0
  245. aiecs/tools/docs/document_parser_tool.py +994 -0
  246. aiecs/tools/docs/document_writer_tool.py +1818 -0
  247. aiecs/tools/knowledge_graph/__init__.py +17 -0
  248. aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
  249. aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
  250. aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
  251. aiecs/tools/langchain_adapter.py +542 -0
  252. aiecs/tools/schema_generator.py +275 -0
  253. aiecs/tools/search_tool/__init__.py +100 -0
  254. aiecs/tools/search_tool/analyzers.py +589 -0
  255. aiecs/tools/search_tool/cache.py +260 -0
  256. aiecs/tools/search_tool/constants.py +128 -0
  257. aiecs/tools/search_tool/context.py +216 -0
  258. aiecs/tools/search_tool/core.py +749 -0
  259. aiecs/tools/search_tool/deduplicator.py +123 -0
  260. aiecs/tools/search_tool/error_handler.py +271 -0
  261. aiecs/tools/search_tool/metrics.py +371 -0
  262. aiecs/tools/search_tool/rate_limiter.py +178 -0
  263. aiecs/tools/search_tool/schemas.py +277 -0
  264. aiecs/tools/statistics/__init__.py +80 -0
  265. aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
  266. aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
  267. aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
  268. aiecs/tools/statistics/data_loader_tool.py +564 -0
  269. aiecs/tools/statistics/data_profiler_tool.py +658 -0
  270. aiecs/tools/statistics/data_transformer_tool.py +573 -0
  271. aiecs/tools/statistics/data_visualizer_tool.py +495 -0
  272. aiecs/tools/statistics/model_trainer_tool.py +487 -0
  273. aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
  274. aiecs/tools/task_tools/__init__.py +86 -0
  275. aiecs/tools/task_tools/chart_tool.py +732 -0
  276. aiecs/tools/task_tools/classfire_tool.py +922 -0
  277. aiecs/tools/task_tools/image_tool.py +447 -0
  278. aiecs/tools/task_tools/office_tool.py +684 -0
  279. aiecs/tools/task_tools/pandas_tool.py +635 -0
  280. aiecs/tools/task_tools/report_tool.py +635 -0
  281. aiecs/tools/task_tools/research_tool.py +392 -0
  282. aiecs/tools/task_tools/scraper_tool.py +715 -0
  283. aiecs/tools/task_tools/stats_tool.py +688 -0
  284. aiecs/tools/temp_file_manager.py +130 -0
  285. aiecs/tools/tool_executor/__init__.py +37 -0
  286. aiecs/tools/tool_executor/tool_executor.py +881 -0
  287. aiecs/utils/LLM_output_structor.py +445 -0
  288. aiecs/utils/__init__.py +34 -0
  289. aiecs/utils/base_callback.py +47 -0
  290. aiecs/utils/cache_provider.py +695 -0
  291. aiecs/utils/execution_utils.py +184 -0
  292. aiecs/utils/logging.py +1 -0
  293. aiecs/utils/prompt_loader.py +14 -0
  294. aiecs/utils/token_usage_repository.py +323 -0
  295. aiecs/ws/__init__.py +0 -0
  296. aiecs/ws/socket_server.py +52 -0
  297. aiecs-1.5.1.dist-info/METADATA +608 -0
  298. aiecs-1.5.1.dist-info/RECORD +302 -0
  299. aiecs-1.5.1.dist-info/WHEEL +5 -0
  300. aiecs-1.5.1.dist-info/entry_points.txt +10 -0
  301. aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
  302. aiecs-1.5.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,29 @@
1
+ """
2
+ Prompt Templates Module
3
+
4
+ Native prompt template system replacing LangChain templates.
5
+ """
6
+
7
+ from .template import (
8
+ PromptTemplate,
9
+ ChatPromptTemplate,
10
+ MessageTemplate,
11
+ TemplateMissingVariableError,
12
+ )
13
+ from .builder import MessageBuilder
14
+ from .formatters import (
15
+ format_conversation_history,
16
+ format_tool_result,
17
+ truncate_context,
18
+ )
19
+
20
+ __all__ = [
21
+ "PromptTemplate",
22
+ "ChatPromptTemplate",
23
+ "MessageTemplate",
24
+ "TemplateMissingVariableError",
25
+ "MessageBuilder",
26
+ "format_conversation_history",
27
+ "format_tool_result",
28
+ "truncate_context",
29
+ ]
@@ -0,0 +1,161 @@
1
+ """
2
+ Message Builder
3
+
4
+ Helper for constructing LLMMessage lists.
5
+ """
6
+
7
+ from typing import List, Dict, Any, Optional
8
+ from aiecs.llm import LLMMessage
9
+
10
+
11
+ class MessageBuilder:
12
+ """
13
+ Builder for constructing LLM message sequences.
14
+
15
+ Example:
16
+ builder = MessageBuilder()
17
+ builder.add_system("You are a helpful assistant")
18
+ builder.add_user("What is AI?")
19
+ messages = builder.build()
20
+ """
21
+
22
+ def __init__(self):
23
+ """Initialize message builder."""
24
+ self.messages: List[LLMMessage] = []
25
+
26
+ def add_system(self, content: str) -> "MessageBuilder":
27
+ """
28
+ Add system message.
29
+
30
+ Args:
31
+ content: Message content
32
+
33
+ Returns:
34
+ Self for chaining
35
+ """
36
+ self.messages.append(LLMMessage(role="system", content=content))
37
+ return self
38
+
39
+ def add_user(self, content: str) -> "MessageBuilder":
40
+ """
41
+ Add user message.
42
+
43
+ Args:
44
+ content: Message content
45
+
46
+ Returns:
47
+ Self for chaining
48
+ """
49
+ self.messages.append(LLMMessage(role="user", content=content))
50
+ return self
51
+
52
+ def add_assistant(self, content: str) -> "MessageBuilder":
53
+ """
54
+ Add assistant message.
55
+
56
+ Args:
57
+ content: Message content
58
+
59
+ Returns:
60
+ Self for chaining
61
+ """
62
+ self.messages.append(LLMMessage(role="assistant", content=content))
63
+ return self
64
+
65
+ def add_message(self, role: str, content: str) -> "MessageBuilder":
66
+ """
67
+ Add message with custom role.
68
+
69
+ Args:
70
+ role: Message role
71
+ content: Message content
72
+
73
+ Returns:
74
+ Self for chaining
75
+ """
76
+ self.messages.append(LLMMessage(role=role, content=content))
77
+ return self
78
+
79
+ def add_messages(self, messages: List[LLMMessage]) -> "MessageBuilder":
80
+ """
81
+ Add multiple messages.
82
+
83
+ Args:
84
+ messages: List of messages to add
85
+
86
+ Returns:
87
+ Self for chaining
88
+ """
89
+ self.messages.extend(messages)
90
+ return self
91
+
92
+ def add_context(self, context: Dict[str, Any], prefix: str = "Context:") -> "MessageBuilder":
93
+ """
94
+ Add context as a system message.
95
+
96
+ Args:
97
+ context: Context dictionary
98
+ prefix: Prefix for context message
99
+
100
+ Returns:
101
+ Self for chaining
102
+ """
103
+ context_str = self._format_context(context)
104
+ if context_str:
105
+ self.add_system(f"{prefix}\n{context_str}")
106
+ return self
107
+
108
+ def add_conversation_history(
109
+ self, history: List[Dict[str, str]], max_messages: Optional[int] = None
110
+ ) -> "MessageBuilder":
111
+ """
112
+ Add conversation history.
113
+
114
+ Args:
115
+ history: List of {role, content} dicts
116
+ max_messages: Optional limit on number of messages
117
+
118
+ Returns:
119
+ Self for chaining
120
+ """
121
+ if max_messages:
122
+ history = history[-max_messages:]
123
+
124
+ for msg in history:
125
+ self.add_message(msg.get("role", "user"), msg.get("content", ""))
126
+
127
+ return self
128
+
129
+ def clear(self) -> "MessageBuilder":
130
+ """
131
+ Clear all messages.
132
+
133
+ Returns:
134
+ Self for chaining
135
+ """
136
+ self.messages.clear()
137
+ return self
138
+
139
+ def build(self) -> List[LLMMessage]:
140
+ """
141
+ Build and return message list.
142
+
143
+ Returns:
144
+ List of LLMMessage instances
145
+ """
146
+ return self.messages.copy()
147
+
148
+ def _format_context(self, context: Dict[str, Any]) -> str:
149
+ """Format context dictionary as string."""
150
+ lines = []
151
+ for key, value in context.items():
152
+ if not key.startswith("_") and value is not None:
153
+ lines.append(f"{key}: {value}")
154
+ return "\n".join(lines) if lines else ""
155
+
156
+ def __len__(self) -> int:
157
+ """Get number of messages."""
158
+ return len(self.messages)
159
+
160
+ def __repr__(self) -> str:
161
+ return f"MessageBuilder(messages={len(self.messages)})"
@@ -0,0 +1,189 @@
1
+ """
2
+ Prompt Formatters
3
+
4
+ Utilities for formatting prompts with context.
5
+ """
6
+
7
+ from typing import List, Dict, Any, Optional
8
+ from aiecs.llm import LLMMessage
9
+
10
+
11
+ def format_conversation_history(
12
+ history: List[LLMMessage],
13
+ max_messages: Optional[int] = None,
14
+ format_style: str = "compact",
15
+ ) -> str:
16
+ """
17
+ Format conversation history as string.
18
+
19
+ Args:
20
+ history: List of LLMMessage instances
21
+ max_messages: Optional limit on number of messages
22
+ format_style: "compact" or "detailed"
23
+
24
+ Returns:
25
+ Formatted conversation string
26
+ """
27
+ if max_messages:
28
+ history = history[-max_messages:]
29
+
30
+ if format_style == "compact":
31
+ lines = []
32
+ for msg in history:
33
+ lines.append(f"{msg.role.upper()}: {msg.content}")
34
+ return "\n".join(lines)
35
+
36
+ elif format_style == "detailed":
37
+ lines = []
38
+ for i, msg in enumerate(history):
39
+ lines.append(f"[{i+1}] {msg.role.upper()}")
40
+ lines.append(msg.content)
41
+ lines.append("") # Empty line between messages
42
+ return "\n".join(lines)
43
+
44
+ else:
45
+ raise ValueError(f"Unknown format_style: {format_style}")
46
+
47
+
48
+ def format_tool_result(
49
+ tool_name: str,
50
+ result: Any,
51
+ success: bool = True,
52
+ error: Optional[str] = None,
53
+ ) -> str:
54
+ """
55
+ Format tool execution result.
56
+
57
+ Args:
58
+ tool_name: Tool name
59
+ result: Tool result (if successful)
60
+ success: Whether execution succeeded
61
+ error: Error message (if failed)
62
+
63
+ Returns:
64
+ Formatted tool result string
65
+ """
66
+ if success:
67
+ return f"Tool '{tool_name}' returned:\n{result}"
68
+ else:
69
+ return f"Tool '{tool_name}' failed: {error}"
70
+
71
+
72
+ def truncate_context(
73
+ text: str,
74
+ max_length: int,
75
+ strategy: str = "middle",
76
+ placeholder: str = "...",
77
+ ) -> str:
78
+ """
79
+ Truncate text to fit within max_length.
80
+
81
+ Args:
82
+ text: Text to truncate
83
+ max_length: Maximum length
84
+ strategy: "start", "middle", or "end"
85
+ placeholder: Placeholder for truncated content
86
+
87
+ Returns:
88
+ Truncated text
89
+ """
90
+ if len(text) <= max_length:
91
+ return text
92
+
93
+ if strategy == "end":
94
+ # Keep start, truncate end
95
+ return text[: max_length - len(placeholder)] + placeholder
96
+
97
+ elif strategy == "start":
98
+ # Truncate start, keep end
99
+ return placeholder + text[-(max_length - len(placeholder)) :]
100
+
101
+ elif strategy == "middle":
102
+ # Keep start and end, truncate middle
103
+ half = (max_length - len(placeholder)) // 2
104
+ return text[:half] + placeholder + text[-half:]
105
+
106
+ else:
107
+ raise ValueError(f"Unknown strategy: {strategy}")
108
+
109
+
110
+ def format_list_items(items: List[str], style: str = "bullets") -> str:
111
+ """
112
+ Format list items.
113
+
114
+ Args:
115
+ items: List of items
116
+ style: "bullets", "numbered", or "compact"
117
+
118
+ Returns:
119
+ Formatted list string
120
+ """
121
+ if style == "bullets":
122
+ return "\n".join(f"• {item}" for item in items)
123
+
124
+ elif style == "numbered":
125
+ return "\n".join(f"{i+1}. {item}" for i, item in enumerate(items))
126
+
127
+ elif style == "compact":
128
+ return ", ".join(items)
129
+
130
+ else:
131
+ raise ValueError(f"Unknown style: {style}")
132
+
133
+
134
+ def format_key_value_pairs(
135
+ data: Dict[str, Any],
136
+ separator: str = ": ",
137
+ exclude_keys: Optional[List[str]] = None,
138
+ ) -> str:
139
+ """
140
+ Format dictionary as key-value pairs.
141
+
142
+ Args:
143
+ data: Dictionary to format
144
+ separator: Separator between key and value
145
+ exclude_keys: Keys to exclude
146
+
147
+ Returns:
148
+ Formatted string
149
+ """
150
+ exclude_keys = exclude_keys or []
151
+ lines = []
152
+
153
+ for key, value in data.items():
154
+ if key in exclude_keys or key.startswith("_"):
155
+ continue
156
+ lines.append(f"{key}{separator}{value}")
157
+
158
+ return "\n".join(lines)
159
+
160
+
161
+ def inject_context_in_prompt(
162
+ prompt: str, context: Dict[str, Any], context_marker: str = "{context}"
163
+ ) -> str:
164
+ """
165
+ Inject context into prompt at marker position.
166
+
167
+ Args:
168
+ prompt: Prompt template with context marker
169
+ context: Context dictionary
170
+ context_marker: Marker to replace with context
171
+
172
+ Returns:
173
+ Prompt with context injected
174
+ """
175
+ context_str = format_key_value_pairs(context)
176
+ return prompt.replace(context_marker, context_str)
177
+
178
+
179
+ def estimate_token_count(text: str) -> int:
180
+ """
181
+ Rough estimation of token count.
182
+
183
+ Args:
184
+ text: Text to estimate
185
+
186
+ Returns:
187
+ Estimated token count (4 chars ≈ 1 token)
188
+ """
189
+ return len(text) // 4
@@ -0,0 +1,255 @@
1
+ """
2
+ Prompt Templates
3
+
4
+ Native template system with variable substitution.
5
+ """
6
+
7
+ import re
8
+ from typing import Dict, List, Optional
9
+ from dataclasses import dataclass
10
+
11
+ from aiecs.llm import LLMMessage
12
+
13
+
14
+ class TemplateMissingVariableError(Exception):
15
+ """Raised when required template variable is missing."""
16
+
17
+
18
+ class PromptTemplate:
19
+ """
20
+ String-based prompt template with {variable} substitution.
21
+
22
+ Example:
23
+ template = PromptTemplate(
24
+ "Hello {name}, you are a {role}.",
25
+ required_variables=["name", "role"]
26
+ )
27
+ result = template.format(name="Alice", role="developer")
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ template: str,
33
+ required_variables: Optional[List[str]] = None,
34
+ defaults: Optional[Dict[str, str]] = None,
35
+ ):
36
+ """
37
+ Initialize prompt template.
38
+
39
+ Args:
40
+ template: Template string with {variable} placeholders
41
+ required_variables: List of required variable names
42
+ defaults: Default values for optional variables
43
+ """
44
+ self.template = template
45
+ self.required_variables = required_variables or []
46
+ self.defaults = defaults or {}
47
+
48
+ # Extract all variables from template
49
+ self._extract_variables()
50
+
51
+ def _extract_variables(self) -> None:
52
+ """Extract variable names from template."""
53
+ # Find all {variable_name} patterns
54
+ pattern = r"\{(\w+)\}"
55
+ self.variables = set(re.findall(pattern, self.template))
56
+
57
+ def format(self, **kwargs) -> str:
58
+ """
59
+ Format template with provided variables.
60
+
61
+ Args:
62
+ **kwargs: Variable values
63
+
64
+ Returns:
65
+ Formatted string
66
+
67
+ Raises:
68
+ TemplateMissingVariableError: If required variable missing
69
+ """
70
+ # Check required variables
71
+ for var in self.required_variables:
72
+ if var not in kwargs and var not in self.defaults:
73
+ raise TemplateMissingVariableError(f"Required variable '{var}' not provided")
74
+
75
+ # Merge with defaults
76
+ values = {**self.defaults, **kwargs}
77
+
78
+ # Format template
79
+ try:
80
+ return self.template.format(**values)
81
+ except KeyError as e:
82
+ raise TemplateMissingVariableError(f"Variable {e} not provided and has no default")
83
+
84
+ def partial(self, **kwargs) -> "PromptTemplate":
85
+ """
86
+ Create a partial template with some variables pre-filled.
87
+
88
+ Args:
89
+ **kwargs: Variable values to pre-fill
90
+
91
+ Returns:
92
+ New PromptTemplate with updated defaults
93
+ """
94
+ new_defaults = {**self.defaults, **kwargs}
95
+ return PromptTemplate(
96
+ template=self.template,
97
+ required_variables=self.required_variables,
98
+ defaults=new_defaults,
99
+ )
100
+
101
+ def __repr__(self) -> str:
102
+ return f"PromptTemplate(variables={self.variables})"
103
+
104
+
105
+ @dataclass
106
+ class MessageTemplate:
107
+ """Template for a single message."""
108
+
109
+ role: str
110
+ content: str
111
+
112
+
113
+ class ChatPromptTemplate:
114
+ """
115
+ Multi-message chat template.
116
+
117
+ Example:
118
+ template = ChatPromptTemplate([
119
+ MessageTemplate("system", "You are a {role}."),
120
+ MessageTemplate("user", "{task}"),
121
+ ])
122
+ messages = template.format_messages(role="assistant", task="Help me")
123
+ """
124
+
125
+ def __init__(
126
+ self,
127
+ messages: List[MessageTemplate],
128
+ required_variables: Optional[List[str]] = None,
129
+ defaults: Optional[Dict[str, str]] = None,
130
+ ):
131
+ """
132
+ Initialize chat template.
133
+
134
+ Args:
135
+ messages: List of message templates
136
+ required_variables: List of required variable names
137
+ defaults: Default values for optional variables
138
+ """
139
+ self.messages = messages
140
+ self.required_variables = required_variables or []
141
+ self.defaults = defaults or {}
142
+
143
+ # Extract all variables
144
+ self._extract_variables()
145
+
146
+ def _extract_variables(self) -> None:
147
+ """Extract variables from all message templates."""
148
+ self.variables = set()
149
+ pattern = r"\{(\w+)\}"
150
+
151
+ for msg in self.messages:
152
+ vars_in_msg = set(re.findall(pattern, msg.content))
153
+ self.variables.update(vars_in_msg)
154
+
155
+ def format_messages(self, **kwargs) -> List[LLMMessage]:
156
+ """
157
+ Format all messages with provided variables.
158
+
159
+ Args:
160
+ **kwargs: Variable values
161
+
162
+ Returns:
163
+ List of LLMMessage instances
164
+
165
+ Raises:
166
+ TemplateMissingVariableError: If required variable missing
167
+ """
168
+ # Check required variables
169
+ for var in self.required_variables:
170
+ if var not in kwargs and var not in self.defaults:
171
+ raise TemplateMissingVariableError(f"Required variable '{var}' not provided")
172
+
173
+ # Merge with defaults
174
+ values = {**self.defaults, **kwargs}
175
+
176
+ # Format each message
177
+ formatted_messages = []
178
+ for msg_template in self.messages:
179
+ try:
180
+ content = msg_template.content.format(**values)
181
+ formatted_messages.append(LLMMessage(role=msg_template.role, content=content))
182
+ except KeyError as e:
183
+ raise TemplateMissingVariableError(f"Variable {e} not provided and has no default")
184
+
185
+ return formatted_messages
186
+
187
+ def partial(self, **kwargs) -> "ChatPromptTemplate":
188
+ """
189
+ Create a partial template with some variables pre-filled.
190
+
191
+ Args:
192
+ **kwargs: Variable values to pre-fill
193
+
194
+ Returns:
195
+ New ChatPromptTemplate with updated defaults
196
+ """
197
+ new_defaults = {**self.defaults, **kwargs}
198
+ return ChatPromptTemplate(
199
+ messages=self.messages,
200
+ required_variables=self.required_variables,
201
+ defaults=new_defaults,
202
+ )
203
+
204
+ def add_message(self, role: str, content: str) -> "ChatPromptTemplate":
205
+ """
206
+ Add a message to the template.
207
+
208
+ Args:
209
+ role: Message role
210
+ content: Message content template
211
+
212
+ Returns:
213
+ New ChatPromptTemplate with added message
214
+ """
215
+ new_messages = self.messages + [MessageTemplate(role, content)]
216
+ return ChatPromptTemplate(
217
+ messages=new_messages,
218
+ required_variables=self.required_variables,
219
+ defaults=self.defaults,
220
+ )
221
+
222
+ def __repr__(self) -> str:
223
+ return f"ChatPromptTemplate(messages={len(self.messages)}, variables={self.variables})"
224
+
225
+
226
+ def create_system_prompt(content: str) -> ChatPromptTemplate:
227
+ """
228
+ Helper to create a chat template with system message.
229
+
230
+ Args:
231
+ content: System message content
232
+
233
+ Returns:
234
+ ChatPromptTemplate with system message
235
+ """
236
+ return ChatPromptTemplate([MessageTemplate("system", content)])
237
+
238
+
239
+ def create_basic_chat(system: str, user: str) -> ChatPromptTemplate:
240
+ """
241
+ Helper to create a basic system + user chat template.
242
+
243
+ Args:
244
+ system: System message content
245
+ user: User message content
246
+
247
+ Returns:
248
+ ChatPromptTemplate with system and user messages
249
+ """
250
+ return ChatPromptTemplate(
251
+ [
252
+ MessageTemplate("system", system),
253
+ MessageTemplate("user", user),
254
+ ]
255
+ )