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.
- aiecs/__init__.py +72 -0
- aiecs/__main__.py +41 -0
- aiecs/aiecs_client.py +469 -0
- aiecs/application/__init__.py +10 -0
- aiecs/application/executors/__init__.py +10 -0
- aiecs/application/executors/operation_executor.py +363 -0
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +375 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +356 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +531 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +443 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +319 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +100 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +327 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +349 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +244 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +23 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +387 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +343 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +580 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +189 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +344 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +378 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +199 -0
- aiecs/application/knowledge_graph/profiling/query_profiler.py +223 -0
- aiecs/application/knowledge_graph/reasoning/__init__.py +27 -0
- aiecs/application/knowledge_graph/reasoning/evidence_synthesis.py +347 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +504 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +167 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/__init__.py +79 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_builder.py +513 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_nodes.py +630 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +654 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +477 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +390 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +217 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +169 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +872 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +554 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +19 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +596 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +423 -0
- aiecs/application/knowledge_graph/search/reranker.py +295 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +553 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +398 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +329 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +269 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +189 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +321 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +484 -0
- aiecs/config/__init__.py +16 -0
- aiecs/config/config.py +498 -0
- aiecs/config/graph_config.py +137 -0
- aiecs/config/registry.py +23 -0
- aiecs/core/__init__.py +46 -0
- aiecs/core/interface/__init__.py +34 -0
- aiecs/core/interface/execution_interface.py +152 -0
- aiecs/core/interface/storage_interface.py +171 -0
- aiecs/domain/__init__.py +289 -0
- aiecs/domain/agent/__init__.py +189 -0
- aiecs/domain/agent/base_agent.py +697 -0
- aiecs/domain/agent/exceptions.py +103 -0
- aiecs/domain/agent/graph_aware_mixin.py +559 -0
- aiecs/domain/agent/hybrid_agent.py +490 -0
- aiecs/domain/agent/integration/__init__.py +26 -0
- aiecs/domain/agent/integration/context_compressor.py +222 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +252 -0
- aiecs/domain/agent/integration/retry_policy.py +219 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +646 -0
- aiecs/domain/agent/lifecycle.py +296 -0
- aiecs/domain/agent/llm_agent.py +300 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +197 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +160 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +90 -0
- aiecs/domain/agent/models.py +317 -0
- aiecs/domain/agent/observability.py +407 -0
- aiecs/domain/agent/persistence.py +289 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +161 -0
- aiecs/domain/agent/prompts/formatters.py +189 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +260 -0
- aiecs/domain/agent/tool_agent.py +257 -0
- aiecs/domain/agent/tools/__init__.py +12 -0
- aiecs/domain/agent/tools/schema_generator.py +221 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +477 -0
- aiecs/domain/community/analytics.py +481 -0
- aiecs/domain/community/collaborative_workflow.py +642 -0
- aiecs/domain/community/communication_hub.py +645 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +800 -0
- aiecs/domain/community/community_manager.py +813 -0
- aiecs/domain/community/decision_engine.py +879 -0
- aiecs/domain/community/exceptions.py +225 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +268 -0
- aiecs/domain/community/resource_manager.py +457 -0
- aiecs/domain/community/shared_context_manager.py +603 -0
- aiecs/domain/context/__init__.py +58 -0
- aiecs/domain/context/context_engine.py +989 -0
- aiecs/domain/context/conversation_models.py +354 -0
- aiecs/domain/context/graph_memory.py +467 -0
- aiecs/domain/execution/__init__.py +12 -0
- aiecs/domain/execution/model.py +57 -0
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +130 -0
- aiecs/domain/knowledge_graph/models/evidence.py +194 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +186 -0
- aiecs/domain/knowledge_graph/models/path.py +179 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +173 -0
- aiecs/domain/knowledge_graph/models/query.py +272 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +187 -0
- aiecs/domain/knowledge_graph/models/relation.py +136 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +135 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +271 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +155 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +171 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +496 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +205 -0
- aiecs/domain/task/__init__.py +13 -0
- aiecs/domain/task/dsl_processor.py +613 -0
- aiecs/domain/task/model.py +62 -0
- aiecs/domain/task/task_context.py +268 -0
- aiecs/infrastructure/__init__.py +24 -0
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +601 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +449 -0
- aiecs/infrastructure/graph_storage/cache.py +429 -0
- aiecs/infrastructure/graph_storage/distributed.py +226 -0
- aiecs/infrastructure/graph_storage/error_handling.py +390 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +306 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +514 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +483 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +410 -0
- aiecs/infrastructure/graph_storage/metrics.py +357 -0
- aiecs/infrastructure/graph_storage/migration.py +413 -0
- aiecs/infrastructure/graph_storage/pagination.py +471 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +466 -0
- aiecs/infrastructure/graph_storage/postgres.py +871 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +635 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +623 -0
- aiecs/infrastructure/graph_storage/streaming.py +495 -0
- aiecs/infrastructure/messaging/__init__.py +13 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +383 -0
- aiecs/infrastructure/messaging/websocket_manager.py +298 -0
- aiecs/infrastructure/monitoring/__init__.py +34 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +174 -0
- aiecs/infrastructure/monitoring/global_metrics_manager.py +213 -0
- aiecs/infrastructure/monitoring/structured_logger.py +48 -0
- aiecs/infrastructure/monitoring/tracing_manager.py +410 -0
- aiecs/infrastructure/persistence/__init__.py +24 -0
- aiecs/infrastructure/persistence/context_engine_client.py +187 -0
- aiecs/infrastructure/persistence/database_manager.py +333 -0
- aiecs/infrastructure/persistence/file_storage.py +754 -0
- aiecs/infrastructure/persistence/redis_client.py +220 -0
- aiecs/llm/__init__.py +86 -0
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/callbacks/custom_callbacks.py +264 -0
- aiecs/llm/client_factory.py +420 -0
- aiecs/llm/clients/__init__.py +33 -0
- aiecs/llm/clients/base_client.py +193 -0
- aiecs/llm/clients/googleai_client.py +181 -0
- aiecs/llm/clients/openai_client.py +131 -0
- aiecs/llm/clients/vertex_client.py +437 -0
- aiecs/llm/clients/xai_client.py +184 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +275 -0
- aiecs/llm/config/config_validator.py +236 -0
- aiecs/llm/config/model_config.py +151 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +91 -0
- aiecs/main.py +363 -0
- aiecs/scripts/__init__.py +3 -0
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +97 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/version_manager.py +215 -0
- aiecs/scripts/dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md +242 -0
- aiecs/scripts/dependance_check/README_DEPENDENCY_CHECKER.md +310 -0
- aiecs/scripts/dependance_check/__init__.py +17 -0
- aiecs/scripts/dependance_check/dependency_checker.py +938 -0
- aiecs/scripts/dependance_check/dependency_fixer.py +391 -0
- aiecs/scripts/dependance_check/download_nlp_data.py +396 -0
- aiecs/scripts/dependance_check/quick_dependency_check.py +270 -0
- aiecs/scripts/dependance_check/setup_nlp_data.sh +217 -0
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/README_WEASEL_PATCH.md +126 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.py +128 -0
- aiecs/scripts/dependance_patch/fix_weasel/fix_weasel_validator.sh +82 -0
- aiecs/scripts/dependance_patch/fix_weasel/patch_weasel_library.sh +188 -0
- aiecs/scripts/dependance_patch/fix_weasel/run_weasel_patch.sh +41 -0
- aiecs/scripts/tools_develop/README.md +449 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +259 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +422 -0
- aiecs/scripts/tools_develop/verify_tools.py +356 -0
- aiecs/tasks/__init__.py +1 -0
- aiecs/tasks/worker.py +172 -0
- aiecs/tools/__init__.py +299 -0
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +381 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +413 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +388 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +303 -0
- aiecs/tools/apisource/providers/__init__.py +115 -0
- aiecs/tools/apisource/providers/base.py +664 -0
- aiecs/tools/apisource/providers/census.py +401 -0
- aiecs/tools/apisource/providers/fred.py +564 -0
- aiecs/tools/apisource/providers/newsapi.py +412 -0
- aiecs/tools/apisource/providers/worldbank.py +357 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +375 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +391 -0
- aiecs/tools/apisource/tool.py +850 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +338 -0
- aiecs/tools/base_tool.py +201 -0
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +599 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2403 -0
- aiecs/tools/docs/content_insertion_tool.py +1333 -0
- aiecs/tools/docs/document_creator_tool.py +1317 -0
- aiecs/tools/docs/document_layout_tool.py +1166 -0
- aiecs/tools/docs/document_parser_tool.py +994 -0
- aiecs/tools/docs/document_writer_tool.py +1818 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +734 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +923 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +476 -0
- aiecs/tools/langchain_adapter.py +542 -0
- aiecs/tools/schema_generator.py +275 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +589 -0
- aiecs/tools/search_tool/cache.py +260 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +216 -0
- aiecs/tools/search_tool/core.py +749 -0
- aiecs/tools/search_tool/deduplicator.py +123 -0
- aiecs/tools/search_tool/error_handler.py +271 -0
- aiecs/tools/search_tool/metrics.py +371 -0
- aiecs/tools/search_tool/rate_limiter.py +178 -0
- aiecs/tools/search_tool/schemas.py +277 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +643 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +505 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +694 -0
- aiecs/tools/statistics/data_loader_tool.py +564 -0
- aiecs/tools/statistics/data_profiler_tool.py +658 -0
- aiecs/tools/statistics/data_transformer_tool.py +573 -0
- aiecs/tools/statistics/data_visualizer_tool.py +495 -0
- aiecs/tools/statistics/model_trainer_tool.py +487 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +459 -0
- aiecs/tools/task_tools/__init__.py +86 -0
- aiecs/tools/task_tools/chart_tool.py +732 -0
- aiecs/tools/task_tools/classfire_tool.py +922 -0
- aiecs/tools/task_tools/image_tool.py +447 -0
- aiecs/tools/task_tools/office_tool.py +684 -0
- aiecs/tools/task_tools/pandas_tool.py +635 -0
- aiecs/tools/task_tools/report_tool.py +635 -0
- aiecs/tools/task_tools/research_tool.py +392 -0
- aiecs/tools/task_tools/scraper_tool.py +715 -0
- aiecs/tools/task_tools/stats_tool.py +688 -0
- aiecs/tools/temp_file_manager.py +130 -0
- aiecs/tools/tool_executor/__init__.py +37 -0
- aiecs/tools/tool_executor/tool_executor.py +881 -0
- aiecs/utils/LLM_output_structor.py +445 -0
- aiecs/utils/__init__.py +34 -0
- aiecs/utils/base_callback.py +47 -0
- aiecs/utils/cache_provider.py +695 -0
- aiecs/utils/execution_utils.py +184 -0
- aiecs/utils/logging.py +1 -0
- aiecs/utils/prompt_loader.py +14 -0
- aiecs/utils/token_usage_repository.py +323 -0
- aiecs/ws/__init__.py +0 -0
- aiecs/ws/socket_server.py +52 -0
- aiecs-1.5.1.dist-info/METADATA +608 -0
- aiecs-1.5.1.dist-info/RECORD +302 -0
- aiecs-1.5.1.dist-info/WHEEL +5 -0
- aiecs-1.5.1.dist-info/entry_points.txt +10 -0
- aiecs-1.5.1.dist-info/licenses/LICENSE +225 -0
- aiecs-1.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM Output Structor - Readability and Tone Enhancer
|
|
3
|
+
|
|
4
|
+
This module transforms LLM outputs to be more readable and natural while preserving
|
|
5
|
+
the reasoning process and technical details. Instead of hiding the thinking process,
|
|
6
|
+
it makes it more accessible and easier to understand.
|
|
7
|
+
|
|
8
|
+
Key transformations:
|
|
9
|
+
1. Add friendly openings and closings
|
|
10
|
+
2. Transform technical jargon to more accessible language
|
|
11
|
+
3. Improve formatting and structure for better readability
|
|
12
|
+
4. Preserve reasoning but make it more conversational
|
|
13
|
+
5. Maintain transparency while improving user experience
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
import json
|
|
18
|
+
from typing import List, Dict, Any, Optional, Union
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class LLMOutputTransformer:
|
|
22
|
+
"""
|
|
23
|
+
Transformer that enhances readability while preserving LLM reasoning and analysis.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
# Word replacements for better readability
|
|
28
|
+
self.technical_replacements = {
|
|
29
|
+
# Technical terms to friendly alternatives
|
|
30
|
+
"demand_state": "request status",
|
|
31
|
+
"VAGUE_UNCLEAR": "needs clarification",
|
|
32
|
+
"SMART_COMPLIANT": "well-defined",
|
|
33
|
+
"SMART_LARGE_SCOPE": "comprehensive but needs focusing",
|
|
34
|
+
"smart_analysis": "detailed analysis",
|
|
35
|
+
"confidence": "certainty level",
|
|
36
|
+
"intent_categories": "identified purposes",
|
|
37
|
+
"complexity_assessment": "complexity evaluation",
|
|
38
|
+
"execution_mode": "approach type",
|
|
39
|
+
"agent_requirements": "required components",
|
|
40
|
+
"meta_architect": "strategic planner",
|
|
41
|
+
"intent_parser": "request analyzer",
|
|
42
|
+
# Analysis terms
|
|
43
|
+
"fails most SMART criteria": "lacks several key details",
|
|
44
|
+
"SMART criteria": "clarity requirements",
|
|
45
|
+
"not Specific": "not specific enough",
|
|
46
|
+
"not Measurable": "missing measurable goals",
|
|
47
|
+
"not Achievable": "unclear if achievable",
|
|
48
|
+
"not Time-bound": "missing timeframe",
|
|
49
|
+
"high-level goal": "general objective",
|
|
50
|
+
"actionable task": "specific action item",
|
|
51
|
+
# Common phrases
|
|
52
|
+
"classic example": "typical case",
|
|
53
|
+
"significant clarification": "more details",
|
|
54
|
+
"multi-stage": "step-by-step",
|
|
55
|
+
"architect_output": "strategic plan",
|
|
56
|
+
"problem_analysis": "situation assessment",
|
|
57
|
+
"intent parsing": "request understanding",
|
|
58
|
+
"blueprint": "detailed plan",
|
|
59
|
+
"roadmap": "action sequence",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# Friendly section headers
|
|
63
|
+
self.section_headers = {
|
|
64
|
+
"Reasoning:": "💭 My Analysis:",
|
|
65
|
+
"Clarification needed": "📝 Questions to Help Me Understand Better",
|
|
66
|
+
"clarification_needed:": "📝 Helpful Questions:",
|
|
67
|
+
"Problem Analysis:": "🔍 Situation Overview:",
|
|
68
|
+
"Solution Approach:": "💡 Recommended Approach:",
|
|
69
|
+
"Key Components:": "🔧 Main Elements:",
|
|
70
|
+
"Confidence:": "📊 Confidence Level:",
|
|
71
|
+
"Intent Categories:": "🎯 Identified Goals:",
|
|
72
|
+
"Complexity:": "📈 Complexity Level:",
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Opening greetings
|
|
76
|
+
self.greetings = {
|
|
77
|
+
"clarification": "Hello! Thank you for reaching out. Let me help you with your request.",
|
|
78
|
+
"confirmation": "Great! I've carefully analyzed your requirements.",
|
|
79
|
+
"completion": "Excellent! I've completed the analysis.",
|
|
80
|
+
"general": "Thank you for your message.",
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Closing messages
|
|
84
|
+
self.closings = {
|
|
85
|
+
"clarification": "\n\n✨ These details will help me provide you with the most accurate and helpful solution!",
|
|
86
|
+
"confirmation": "\n\n🤝 I'm ready to proceed whenever you are. Feel free to ask any questions or suggest modifications!",
|
|
87
|
+
"completion": "\n\n✅ Everything is set up and ready. Let me know if you need any adjustments!",
|
|
88
|
+
"general": "\n\n💬 Please let me know if you need any clarification!",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
def transform_message(
|
|
92
|
+
self,
|
|
93
|
+
content: str,
|
|
94
|
+
message_type: str = "general",
|
|
95
|
+
preserve_structure: bool = True,
|
|
96
|
+
) -> str:
|
|
97
|
+
"""
|
|
98
|
+
Transform LLM output to be more readable while preserving content.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
content: Raw LLM output
|
|
102
|
+
message_type: Type of message ('clarification', 'confirmation', 'completion', 'general')
|
|
103
|
+
preserve_structure: Whether to preserve the original structure
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Enhanced, more readable message
|
|
107
|
+
"""
|
|
108
|
+
# Add appropriate greeting
|
|
109
|
+
result = self._add_greeting(message_type)
|
|
110
|
+
|
|
111
|
+
# Transform the main content
|
|
112
|
+
transformed_content = self._enhance_readability(content)
|
|
113
|
+
|
|
114
|
+
# Special handling for different message types
|
|
115
|
+
if message_type == "clarification":
|
|
116
|
+
transformed_content = self._enhance_clarification(transformed_content)
|
|
117
|
+
elif message_type == "confirmation":
|
|
118
|
+
transformed_content = self._enhance_confirmation(transformed_content)
|
|
119
|
+
|
|
120
|
+
result += "\n\n" + transformed_content
|
|
121
|
+
|
|
122
|
+
# Add appropriate closing
|
|
123
|
+
result += self._add_closing(message_type)
|
|
124
|
+
|
|
125
|
+
return result
|
|
126
|
+
|
|
127
|
+
def _add_greeting(self, message_type: str) -> str:
|
|
128
|
+
"""Add an appropriate greeting based on message type."""
|
|
129
|
+
return self.greetings.get(message_type, self.greetings["general"])
|
|
130
|
+
|
|
131
|
+
def _add_closing(self, message_type: str) -> str:
|
|
132
|
+
"""Add an appropriate closing based on message type."""
|
|
133
|
+
return self.closings.get(message_type, self.closings["general"])
|
|
134
|
+
|
|
135
|
+
def _enhance_readability(self, content: str) -> str:
|
|
136
|
+
"""Enhance readability by replacing technical terms and improving formatting."""
|
|
137
|
+
result = content
|
|
138
|
+
|
|
139
|
+
# Replace section headers with friendly versions
|
|
140
|
+
for old_header, new_header in self.section_headers.items():
|
|
141
|
+
result = result.replace(old_header, new_header)
|
|
142
|
+
|
|
143
|
+
# Replace technical terms with friendly alternatives
|
|
144
|
+
for technical, friendly in self.technical_replacements.items():
|
|
145
|
+
# Case-insensitive replacement
|
|
146
|
+
result = re.sub(
|
|
147
|
+
rf"\b{re.escape(technical)}\b",
|
|
148
|
+
friendly,
|
|
149
|
+
result,
|
|
150
|
+
flags=re.IGNORECASE,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Improve JSON-like structures visibility
|
|
154
|
+
result = self._format_json_structures(result)
|
|
155
|
+
|
|
156
|
+
# Enhance bullet points
|
|
157
|
+
result = self._enhance_bullet_points(result)
|
|
158
|
+
|
|
159
|
+
# Add spacing for better readability
|
|
160
|
+
result = self._improve_spacing(result)
|
|
161
|
+
|
|
162
|
+
return result
|
|
163
|
+
|
|
164
|
+
def _enhance_clarification(self, content: str) -> str:
|
|
165
|
+
"""Special enhancements for clarification messages."""
|
|
166
|
+
# Transform reasoning section to be more conversational
|
|
167
|
+
content = re.sub(
|
|
168
|
+
r"(💭 My Analysis:)(.*?)(?=\n\n|$)",
|
|
169
|
+
lambda m: f"{m.group(1)}\n{self._make_reasoning_conversational(m.group(2))}",
|
|
170
|
+
content,
|
|
171
|
+
flags=re.DOTALL,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Format questions better
|
|
175
|
+
content = self._format_clarification_questions(content)
|
|
176
|
+
|
|
177
|
+
return content
|
|
178
|
+
|
|
179
|
+
def _enhance_confirmation(self, content: str) -> str:
|
|
180
|
+
"""Special enhancements for confirmation messages."""
|
|
181
|
+
# Make technical descriptions more accessible
|
|
182
|
+
content = re.sub(
|
|
183
|
+
r"I have generated a detailed (.*?):(.*?)(?=Do you|Would you|$)",
|
|
184
|
+
r"I've prepared a comprehensive \1 for you:\n\n\2\n",
|
|
185
|
+
content,
|
|
186
|
+
flags=re.DOTALL,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Format proposed plans better
|
|
190
|
+
content = re.sub(
|
|
191
|
+
r"Proposed plan:(.*?)(?=Do you|Would you|$)",
|
|
192
|
+
r"📋 **Proposed Approach:**\n\1\n",
|
|
193
|
+
content,
|
|
194
|
+
flags=re.DOTALL,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
return content
|
|
198
|
+
|
|
199
|
+
def _make_reasoning_conversational(self, reasoning: str) -> str:
|
|
200
|
+
"""Make reasoning more conversational and easier to read."""
|
|
201
|
+
# First, convert perspective from third-person to second-person
|
|
202
|
+
reasoning = self._convert_perspective(reasoning)
|
|
203
|
+
|
|
204
|
+
# Split into sentences for processing
|
|
205
|
+
sentences = reasoning.strip().split(".")
|
|
206
|
+
conversational_parts = []
|
|
207
|
+
|
|
208
|
+
for i, sentence in enumerate(sentences):
|
|
209
|
+
sentence = sentence.strip()
|
|
210
|
+
if not sentence:
|
|
211
|
+
continue
|
|
212
|
+
|
|
213
|
+
# Make the first sentence more natural
|
|
214
|
+
if i == 0:
|
|
215
|
+
# Remove phrases like "is a classic example of" to be more
|
|
216
|
+
# direct
|
|
217
|
+
sentence = re.sub(
|
|
218
|
+
r"is a (?:classic|typical|clear) example of",
|
|
219
|
+
"seems to be",
|
|
220
|
+
sentence,
|
|
221
|
+
)
|
|
222
|
+
sentence = "Looking at what you've shared, " + sentence.lower()
|
|
223
|
+
# For sentences about what's missing
|
|
224
|
+
elif any(
|
|
225
|
+
word in sentence.lower() for word in ["lacks", "missing", "doesn't have", "without"]
|
|
226
|
+
):
|
|
227
|
+
if not sentence.lower().startswith(("i ", "it ", "this ")):
|
|
228
|
+
sentence = "I notice that it " + sentence.lower()
|
|
229
|
+
# For sentences about what's not clear
|
|
230
|
+
elif "not" in sentence.lower() and any(
|
|
231
|
+
word in sentence.lower() for word in ["specific", "clear", "measurable"]
|
|
232
|
+
):
|
|
233
|
+
sentence = re.sub(
|
|
234
|
+
r"it is not",
|
|
235
|
+
"it isn't quite",
|
|
236
|
+
sentence,
|
|
237
|
+
flags=re.IGNORECASE,
|
|
238
|
+
)
|
|
239
|
+
if not sentence.lower().startswith(("i ", "this ")):
|
|
240
|
+
sentence = "I can see that " + sentence.lower()
|
|
241
|
+
# For requirement sentences
|
|
242
|
+
elif any(word in sentence.lower() for word in ["requires", "needs", "must"]):
|
|
243
|
+
sentence = "To help you effectively, " + sentence.lower().replace(
|
|
244
|
+
"the request", "we'll"
|
|
245
|
+
)
|
|
246
|
+
# Default: make it conversational
|
|
247
|
+
else:
|
|
248
|
+
if len(sentence) > 20 and not sentence.lower().startswith(
|
|
249
|
+
("i ", "this ", "that ", "we ")
|
|
250
|
+
):
|
|
251
|
+
sentence = "Additionally, " + sentence.lower()
|
|
252
|
+
|
|
253
|
+
conversational_parts.append(sentence)
|
|
254
|
+
|
|
255
|
+
result = ". ".join(conversational_parts)
|
|
256
|
+
if result and not result.endswith("."):
|
|
257
|
+
result += "."
|
|
258
|
+
|
|
259
|
+
return result
|
|
260
|
+
|
|
261
|
+
def _convert_perspective(self, text: str) -> str:
|
|
262
|
+
"""Convert text from third-person to second-person perspective."""
|
|
263
|
+
# Replace "the user" references with "you"
|
|
264
|
+
text = re.sub(r"the user'?s?\s+", "your ", text, flags=re.IGNORECASE)
|
|
265
|
+
text = re.sub(r"user'?s?\s+", "your ", text, flags=re.IGNORECASE)
|
|
266
|
+
|
|
267
|
+
# Replace "the request" with "your request" or "what you're asking"
|
|
268
|
+
text = re.sub(r"the request", "your request", text, flags=re.IGNORECASE)
|
|
269
|
+
|
|
270
|
+
# Replace "the business" with "your business"
|
|
271
|
+
text = re.sub(r"the business", "your business", text, flags=re.IGNORECASE)
|
|
272
|
+
|
|
273
|
+
# Replace impersonal constructions
|
|
274
|
+
text = re.sub(r"it is (?:a|an)", "this is", text, flags=re.IGNORECASE)
|
|
275
|
+
text = re.sub(
|
|
276
|
+
r"this is (?:a|an) vague",
|
|
277
|
+
"this seems vague",
|
|
278
|
+
text,
|
|
279
|
+
flags=re.IGNORECASE,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
return text
|
|
283
|
+
|
|
284
|
+
def _format_clarification_questions(self, content: str) -> str:
|
|
285
|
+
"""Format clarification questions for better readability."""
|
|
286
|
+
# Find questions section
|
|
287
|
+
questions_match = re.search(r"📝.*?:(.*?)(?=💭|✨|$)", content, re.DOTALL)
|
|
288
|
+
if not questions_match:
|
|
289
|
+
return content
|
|
290
|
+
|
|
291
|
+
questions_text = questions_match.group(1)
|
|
292
|
+
questions = self._extract_questions(questions_text)
|
|
293
|
+
|
|
294
|
+
if questions:
|
|
295
|
+
formatted = "📝 Questions to Help Me Understand Better:\n\n"
|
|
296
|
+
for i, q in enumerate(questions, 1):
|
|
297
|
+
# Clean up the question
|
|
298
|
+
q = q.strip().strip("-*•")
|
|
299
|
+
if not q.endswith("?"):
|
|
300
|
+
q += "?"
|
|
301
|
+
formatted += f"**{i}.** {q}\n\n"
|
|
302
|
+
|
|
303
|
+
# Replace the original questions section
|
|
304
|
+
content = content.replace(questions_match.group(0), formatted)
|
|
305
|
+
|
|
306
|
+
return content
|
|
307
|
+
|
|
308
|
+
def _extract_questions(self, text: str) -> List[str]:
|
|
309
|
+
"""Extract individual questions from text."""
|
|
310
|
+
# Split by semicolons or line breaks
|
|
311
|
+
parts = re.split(r"[;\n]", text)
|
|
312
|
+
questions = []
|
|
313
|
+
|
|
314
|
+
for part in parts:
|
|
315
|
+
part = part.strip()
|
|
316
|
+
if part and not part.startswith("*Reason:"):
|
|
317
|
+
questions.append(part)
|
|
318
|
+
|
|
319
|
+
return questions
|
|
320
|
+
|
|
321
|
+
def _format_json_structures(self, content: str) -> str:
|
|
322
|
+
"""Format JSON-like structures to be more readable."""
|
|
323
|
+
|
|
324
|
+
# Find JSON-like structures
|
|
325
|
+
def format_dict(match):
|
|
326
|
+
try:
|
|
327
|
+
# Extract the dictionary string
|
|
328
|
+
dict_str = match.group(0)
|
|
329
|
+
# Make it more readable
|
|
330
|
+
formatted = dict_str.replace("'", "")
|
|
331
|
+
formatted = formatted.replace("{", "{\n ")
|
|
332
|
+
formatted = formatted.replace(",", ",\n ")
|
|
333
|
+
formatted = formatted.replace("}", "\n}")
|
|
334
|
+
return formatted
|
|
335
|
+
except Exception:
|
|
336
|
+
return match.group(0)
|
|
337
|
+
|
|
338
|
+
# Apply to simple dictionaries
|
|
339
|
+
content = re.sub(r"\{[^{}]+\}", format_dict, content)
|
|
340
|
+
|
|
341
|
+
return content
|
|
342
|
+
|
|
343
|
+
def _enhance_bullet_points(self, content: str) -> str:
|
|
344
|
+
"""Enhance bullet points for better visibility."""
|
|
345
|
+
# Replace various bullet point styles with a consistent one
|
|
346
|
+
content = re.sub(r"^[-*•]\s*", "• ", content, flags=re.MULTILINE)
|
|
347
|
+
content = re.sub(
|
|
348
|
+
r"^\d+\.\s*",
|
|
349
|
+
lambda m: f"**{m.group(0)}**",
|
|
350
|
+
content,
|
|
351
|
+
flags=re.MULTILINE,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
return content
|
|
355
|
+
|
|
356
|
+
def _improve_spacing(self, content: str) -> str:
|
|
357
|
+
"""Improve spacing for better readability."""
|
|
358
|
+
# Add space before emoji headers
|
|
359
|
+
content = re.sub(r"(?<!\n)(💭|📝|🔍|💡|🔧|📊|🎯|📈)", r"\n\n\1", content)
|
|
360
|
+
|
|
361
|
+
# Ensure proper spacing after headers
|
|
362
|
+
content = re.sub(r"(💭|📝|🔍|💡|🔧|📊|🎯|📈)(.*?):", r"\1\2:\n", content)
|
|
363
|
+
|
|
364
|
+
# Clean up excessive newlines
|
|
365
|
+
content = re.sub(r"\n{3,}", "\n\n", content)
|
|
366
|
+
|
|
367
|
+
return content.strip()
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# Convenience functions
|
|
371
|
+
def format_clarification_message(
|
|
372
|
+
questions: List[str],
|
|
373
|
+
round_number: int = 1,
|
|
374
|
+
reasoning: Optional[str] = None,
|
|
375
|
+
) -> str:
|
|
376
|
+
"""
|
|
377
|
+
Format clarification messages with preserved reasoning.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
questions: List of clarification questions
|
|
381
|
+
round_number: Current round number
|
|
382
|
+
reasoning: Optional reasoning to include
|
|
383
|
+
|
|
384
|
+
Returns:
|
|
385
|
+
Formatted message with enhanced readability
|
|
386
|
+
"""
|
|
387
|
+
transformer = LLMOutputTransformer()
|
|
388
|
+
|
|
389
|
+
# Build content
|
|
390
|
+
content = f"Clarification needed (Round {round_number}): "
|
|
391
|
+
content += "; ".join(questions)
|
|
392
|
+
|
|
393
|
+
if reasoning:
|
|
394
|
+
content += f"\n\nReasoning: {reasoning}"
|
|
395
|
+
|
|
396
|
+
return transformer.transform_message(content, "clarification")
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def format_confirmation_message(
|
|
400
|
+
content: Union[str, Dict[str, Any]], confirmation_type: str = "strategy"
|
|
401
|
+
) -> str:
|
|
402
|
+
"""
|
|
403
|
+
Format confirmation messages with preserved technical details.
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
content: Confirmation content
|
|
407
|
+
confirmation_type: Type of confirmation
|
|
408
|
+
|
|
409
|
+
Returns:
|
|
410
|
+
Enhanced confirmation message
|
|
411
|
+
"""
|
|
412
|
+
transformer = LLMOutputTransformer()
|
|
413
|
+
|
|
414
|
+
if isinstance(content, dict):
|
|
415
|
+
content = json.dumps(content, indent=2)
|
|
416
|
+
|
|
417
|
+
return transformer.transform_message(content, "confirmation")
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def enhance_reasoning(reasoning: str) -> str:
|
|
421
|
+
"""
|
|
422
|
+
Enhance reasoning text to be more readable.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
reasoning: Raw reasoning text
|
|
426
|
+
|
|
427
|
+
Returns:
|
|
428
|
+
Enhanced reasoning text
|
|
429
|
+
"""
|
|
430
|
+
transformer = LLMOutputTransformer()
|
|
431
|
+
return transformer._make_reasoning_conversational(reasoning)
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def clean_technical_terms(content: str) -> str:
|
|
435
|
+
"""
|
|
436
|
+
Replace technical terms with user-friendly alternatives.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
content: Content with technical terms
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
Content with friendly terms
|
|
443
|
+
"""
|
|
444
|
+
transformer = LLMOutputTransformer()
|
|
445
|
+
return transformer._enhance_readability(content)
|
aiecs/utils/__init__.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utils module for the Python middleware application.
|
|
3
|
+
|
|
4
|
+
This module provides utility functions including:
|
|
5
|
+
- Prompt loading functionality
|
|
6
|
+
- Token usage tracking
|
|
7
|
+
- Execution utilities
|
|
8
|
+
- Cache provider interfaces and implementations
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from .prompt_loader import get_prompt
|
|
12
|
+
from .token_usage_repository import TokenUsageRepository
|
|
13
|
+
from .execution_utils import ExecutionUtils
|
|
14
|
+
from .cache_provider import (
|
|
15
|
+
ICacheProvider,
|
|
16
|
+
LRUCacheProvider,
|
|
17
|
+
DualLayerCacheProvider,
|
|
18
|
+
RedisCacheProvider,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"get_prompt",
|
|
23
|
+
"TokenUsageRepository",
|
|
24
|
+
"ExecutionUtils",
|
|
25
|
+
"ICacheProvider",
|
|
26
|
+
"LRUCacheProvider",
|
|
27
|
+
"DualLayerCacheProvider",
|
|
28
|
+
"RedisCacheProvider",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
# Version information
|
|
32
|
+
__version__ = "1.0.0"
|
|
33
|
+
__author__ = "Python Middleware Team"
|
|
34
|
+
__description__ = "Utility functions for the middleware application"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Any, List
|
|
2
|
+
import logging
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CustomAsyncCallbackHandler(ABC):
|
|
9
|
+
"""
|
|
10
|
+
Abstract base class for asynchronous callback handlers
|
|
11
|
+
|
|
12
|
+
This is an abstract base class that defines the callback interface for LLM calls.
|
|
13
|
+
All concrete callback handlers should inherit from this class and implement its abstract methods.
|
|
14
|
+
|
|
15
|
+
Uses generic data structures (Dict[str, Any]) instead of specific LLM types
|
|
16
|
+
to avoid circular import issues and maintain clean architecture.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
async def on_llm_start(self, messages: List[dict], **kwargs: Any) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Callback triggered when LLM call starts
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
messages: List of message dictionaries, each containing 'role' and 'content' keys
|
|
26
|
+
**kwargs: Additional parameters such as provider, model, etc.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
async def on_llm_end(self, response: dict, **kwargs: Any) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Callback triggered when LLM call ends successfully
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
response: Response dictionary containing 'content', 'tokens_used', 'model', etc.
|
|
36
|
+
**kwargs: Additional parameters such as provider, model, etc.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
async def on_llm_error(self, error: Exception, **kwargs: Any) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Callback triggered when LLM call encounters an error
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
error: The exception that occurred during the LLM call
|
|
46
|
+
**kwargs: Additional parameters such as provider, model, etc.
|
|
47
|
+
"""
|