aiecs 1.0.1__py3-none-any.whl → 1.7.6__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.
Potentially problematic release.
This version of aiecs might be problematic. Click here for more details.
- aiecs/__init__.py +13 -16
- aiecs/__main__.py +7 -7
- aiecs/aiecs_client.py +269 -75
- aiecs/application/executors/operation_executor.py +79 -54
- aiecs/application/knowledge_graph/__init__.py +7 -0
- aiecs/application/knowledge_graph/builder/__init__.py +37 -0
- aiecs/application/knowledge_graph/builder/data_quality.py +302 -0
- aiecs/application/knowledge_graph/builder/data_reshaping.py +293 -0
- aiecs/application/knowledge_graph/builder/document_builder.py +369 -0
- aiecs/application/knowledge_graph/builder/graph_builder.py +490 -0
- aiecs/application/knowledge_graph/builder/import_optimizer.py +396 -0
- aiecs/application/knowledge_graph/builder/schema_inference.py +462 -0
- aiecs/application/knowledge_graph/builder/schema_mapping.py +563 -0
- aiecs/application/knowledge_graph/builder/structured_pipeline.py +1384 -0
- aiecs/application/knowledge_graph/builder/text_chunker.py +317 -0
- aiecs/application/knowledge_graph/extractors/__init__.py +27 -0
- aiecs/application/knowledge_graph/extractors/base.py +98 -0
- aiecs/application/knowledge_graph/extractors/llm_entity_extractor.py +422 -0
- aiecs/application/knowledge_graph/extractors/llm_relation_extractor.py +347 -0
- aiecs/application/knowledge_graph/extractors/ner_entity_extractor.py +241 -0
- aiecs/application/knowledge_graph/fusion/__init__.py +78 -0
- aiecs/application/knowledge_graph/fusion/ab_testing.py +395 -0
- aiecs/application/knowledge_graph/fusion/abbreviation_expander.py +327 -0
- aiecs/application/knowledge_graph/fusion/alias_index.py +597 -0
- aiecs/application/knowledge_graph/fusion/alias_matcher.py +384 -0
- aiecs/application/knowledge_graph/fusion/cache_coordinator.py +343 -0
- aiecs/application/knowledge_graph/fusion/entity_deduplicator.py +433 -0
- aiecs/application/knowledge_graph/fusion/entity_linker.py +511 -0
- aiecs/application/knowledge_graph/fusion/evaluation_dataset.py +240 -0
- aiecs/application/knowledge_graph/fusion/knowledge_fusion.py +632 -0
- aiecs/application/knowledge_graph/fusion/matching_config.py +489 -0
- aiecs/application/knowledge_graph/fusion/name_normalizer.py +352 -0
- aiecs/application/knowledge_graph/fusion/relation_deduplicator.py +183 -0
- aiecs/application/knowledge_graph/fusion/semantic_name_matcher.py +464 -0
- aiecs/application/knowledge_graph/fusion/similarity_pipeline.py +534 -0
- aiecs/application/knowledge_graph/pattern_matching/__init__.py +21 -0
- aiecs/application/knowledge_graph/pattern_matching/pattern_matcher.py +342 -0
- aiecs/application/knowledge_graph/pattern_matching/query_executor.py +366 -0
- aiecs/application/knowledge_graph/profiling/__init__.py +12 -0
- aiecs/application/knowledge_graph/profiling/query_plan_visualizer.py +195 -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 +341 -0
- aiecs/application/knowledge_graph/reasoning/inference_engine.py +500 -0
- aiecs/application/knowledge_graph/reasoning/logic_form_parser.py +163 -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 +913 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/ast_validator.py +866 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/error_handler.py +475 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/parser.py +396 -0
- aiecs/application/knowledge_graph/reasoning/logic_parser/query_context.py +208 -0
- aiecs/application/knowledge_graph/reasoning/logic_query_integration.py +170 -0
- aiecs/application/knowledge_graph/reasoning/query_planner.py +855 -0
- aiecs/application/knowledge_graph/reasoning/reasoning_engine.py +518 -0
- aiecs/application/knowledge_graph/retrieval/__init__.py +27 -0
- aiecs/application/knowledge_graph/retrieval/query_intent_classifier.py +211 -0
- aiecs/application/knowledge_graph/retrieval/retrieval_strategies.py +592 -0
- aiecs/application/knowledge_graph/retrieval/strategy_types.py +23 -0
- aiecs/application/knowledge_graph/search/__init__.py +59 -0
- aiecs/application/knowledge_graph/search/hybrid_search.py +457 -0
- aiecs/application/knowledge_graph/search/reranker.py +293 -0
- aiecs/application/knowledge_graph/search/reranker_strategies.py +535 -0
- aiecs/application/knowledge_graph/search/text_similarity.py +392 -0
- aiecs/application/knowledge_graph/traversal/__init__.py +15 -0
- aiecs/application/knowledge_graph/traversal/enhanced_traversal.py +305 -0
- aiecs/application/knowledge_graph/traversal/path_scorer.py +271 -0
- aiecs/application/knowledge_graph/validators/__init__.py +13 -0
- aiecs/application/knowledge_graph/validators/relation_validator.py +239 -0
- aiecs/application/knowledge_graph/visualization/__init__.py +11 -0
- aiecs/application/knowledge_graph/visualization/graph_visualizer.py +313 -0
- aiecs/common/__init__.py +9 -0
- aiecs/common/knowledge_graph/__init__.py +17 -0
- aiecs/common/knowledge_graph/runnable.py +471 -0
- aiecs/config/__init__.py +20 -5
- aiecs/config/config.py +762 -31
- aiecs/config/graph_config.py +131 -0
- aiecs/config/tool_config.py +399 -0
- aiecs/core/__init__.py +29 -13
- aiecs/core/interface/__init__.py +2 -2
- aiecs/core/interface/execution_interface.py +22 -22
- aiecs/core/interface/storage_interface.py +37 -88
- aiecs/core/registry/__init__.py +31 -0
- aiecs/core/registry/service_registry.py +92 -0
- aiecs/domain/__init__.py +270 -1
- aiecs/domain/agent/__init__.py +191 -0
- aiecs/domain/agent/base_agent.py +3870 -0
- aiecs/domain/agent/exceptions.py +99 -0
- aiecs/domain/agent/graph_aware_mixin.py +569 -0
- aiecs/domain/agent/hybrid_agent.py +1435 -0
- aiecs/domain/agent/integration/__init__.py +29 -0
- aiecs/domain/agent/integration/context_compressor.py +216 -0
- aiecs/domain/agent/integration/context_engine_adapter.py +587 -0
- aiecs/domain/agent/integration/protocols.py +281 -0
- aiecs/domain/agent/integration/retry_policy.py +218 -0
- aiecs/domain/agent/integration/role_config.py +213 -0
- aiecs/domain/agent/knowledge_aware_agent.py +1892 -0
- aiecs/domain/agent/lifecycle.py +291 -0
- aiecs/domain/agent/llm_agent.py +692 -0
- aiecs/domain/agent/memory/__init__.py +12 -0
- aiecs/domain/agent/memory/conversation.py +1124 -0
- aiecs/domain/agent/migration/__init__.py +14 -0
- aiecs/domain/agent/migration/conversion.py +163 -0
- aiecs/domain/agent/migration/legacy_wrapper.py +86 -0
- aiecs/domain/agent/models.py +884 -0
- aiecs/domain/agent/observability.py +479 -0
- aiecs/domain/agent/persistence.py +449 -0
- aiecs/domain/agent/prompts/__init__.py +29 -0
- aiecs/domain/agent/prompts/builder.py +159 -0
- aiecs/domain/agent/prompts/formatters.py +187 -0
- aiecs/domain/agent/prompts/template.py +255 -0
- aiecs/domain/agent/registry.py +253 -0
- aiecs/domain/agent/tool_agent.py +444 -0
- aiecs/domain/agent/tools/__init__.py +15 -0
- aiecs/domain/agent/tools/schema_generator.py +364 -0
- aiecs/domain/community/__init__.py +155 -0
- aiecs/domain/community/agent_adapter.py +469 -0
- aiecs/domain/community/analytics.py +432 -0
- aiecs/domain/community/collaborative_workflow.py +648 -0
- aiecs/domain/community/communication_hub.py +634 -0
- aiecs/domain/community/community_builder.py +320 -0
- aiecs/domain/community/community_integration.py +796 -0
- aiecs/domain/community/community_manager.py +803 -0
- aiecs/domain/community/decision_engine.py +849 -0
- aiecs/domain/community/exceptions.py +231 -0
- aiecs/domain/community/models/__init__.py +33 -0
- aiecs/domain/community/models/community_models.py +234 -0
- aiecs/domain/community/resource_manager.py +461 -0
- aiecs/domain/community/shared_context_manager.py +589 -0
- aiecs/domain/context/__init__.py +40 -10
- aiecs/domain/context/context_engine.py +1910 -0
- aiecs/domain/context/conversation_models.py +87 -53
- aiecs/domain/context/graph_memory.py +582 -0
- aiecs/domain/execution/model.py +12 -4
- aiecs/domain/knowledge_graph/__init__.py +19 -0
- aiecs/domain/knowledge_graph/models/__init__.py +52 -0
- aiecs/domain/knowledge_graph/models/entity.py +148 -0
- aiecs/domain/knowledge_graph/models/evidence.py +178 -0
- aiecs/domain/knowledge_graph/models/inference_rule.py +184 -0
- aiecs/domain/knowledge_graph/models/path.py +171 -0
- aiecs/domain/knowledge_graph/models/path_pattern.py +171 -0
- aiecs/domain/knowledge_graph/models/query.py +261 -0
- aiecs/domain/knowledge_graph/models/query_plan.py +181 -0
- aiecs/domain/knowledge_graph/models/relation.py +202 -0
- aiecs/domain/knowledge_graph/schema/__init__.py +23 -0
- aiecs/domain/knowledge_graph/schema/entity_type.py +131 -0
- aiecs/domain/knowledge_graph/schema/graph_schema.py +253 -0
- aiecs/domain/knowledge_graph/schema/property_schema.py +143 -0
- aiecs/domain/knowledge_graph/schema/relation_type.py +163 -0
- aiecs/domain/knowledge_graph/schema/schema_manager.py +691 -0
- aiecs/domain/knowledge_graph/schema/type_enums.py +209 -0
- aiecs/domain/task/dsl_processor.py +172 -56
- aiecs/domain/task/model.py +20 -8
- aiecs/domain/task/task_context.py +27 -24
- aiecs/infrastructure/__init__.py +0 -2
- aiecs/infrastructure/graph_storage/__init__.py +11 -0
- aiecs/infrastructure/graph_storage/base.py +837 -0
- aiecs/infrastructure/graph_storage/batch_operations.py +458 -0
- aiecs/infrastructure/graph_storage/cache.py +424 -0
- aiecs/infrastructure/graph_storage/distributed.py +223 -0
- aiecs/infrastructure/graph_storage/error_handling.py +380 -0
- aiecs/infrastructure/graph_storage/graceful_degradation.py +294 -0
- aiecs/infrastructure/graph_storage/health_checks.py +378 -0
- aiecs/infrastructure/graph_storage/in_memory.py +1197 -0
- aiecs/infrastructure/graph_storage/index_optimization.py +446 -0
- aiecs/infrastructure/graph_storage/lazy_loading.py +431 -0
- aiecs/infrastructure/graph_storage/metrics.py +344 -0
- aiecs/infrastructure/graph_storage/migration.py +400 -0
- aiecs/infrastructure/graph_storage/pagination.py +483 -0
- aiecs/infrastructure/graph_storage/performance_monitoring.py +456 -0
- aiecs/infrastructure/graph_storage/postgres.py +1563 -0
- aiecs/infrastructure/graph_storage/property_storage.py +353 -0
- aiecs/infrastructure/graph_storage/protocols.py +76 -0
- aiecs/infrastructure/graph_storage/query_optimizer.py +642 -0
- aiecs/infrastructure/graph_storage/schema_cache.py +290 -0
- aiecs/infrastructure/graph_storage/sqlite.py +1373 -0
- aiecs/infrastructure/graph_storage/streaming.py +487 -0
- aiecs/infrastructure/graph_storage/tenant.py +412 -0
- aiecs/infrastructure/messaging/celery_task_manager.py +92 -54
- aiecs/infrastructure/messaging/websocket_manager.py +51 -35
- aiecs/infrastructure/monitoring/__init__.py +22 -0
- aiecs/infrastructure/monitoring/executor_metrics.py +45 -11
- aiecs/infrastructure/monitoring/global_metrics_manager.py +212 -0
- aiecs/infrastructure/monitoring/structured_logger.py +3 -7
- aiecs/infrastructure/monitoring/tracing_manager.py +63 -35
- aiecs/infrastructure/persistence/__init__.py +14 -1
- aiecs/infrastructure/persistence/context_engine_client.py +184 -0
- aiecs/infrastructure/persistence/database_manager.py +67 -43
- aiecs/infrastructure/persistence/file_storage.py +180 -103
- aiecs/infrastructure/persistence/redis_client.py +74 -21
- aiecs/llm/__init__.py +73 -25
- aiecs/llm/callbacks/__init__.py +11 -0
- aiecs/llm/{custom_callbacks.py → callbacks/custom_callbacks.py} +26 -19
- aiecs/llm/client_factory.py +224 -36
- aiecs/llm/client_resolver.py +155 -0
- aiecs/llm/clients/__init__.py +38 -0
- aiecs/llm/clients/base_client.py +324 -0
- aiecs/llm/clients/google_function_calling_mixin.py +457 -0
- aiecs/llm/clients/googleai_client.py +241 -0
- aiecs/llm/clients/openai_client.py +158 -0
- aiecs/llm/clients/openai_compatible_mixin.py +367 -0
- aiecs/llm/clients/vertex_client.py +897 -0
- aiecs/llm/clients/xai_client.py +201 -0
- aiecs/llm/config/__init__.py +51 -0
- aiecs/llm/config/config_loader.py +272 -0
- aiecs/llm/config/config_validator.py +206 -0
- aiecs/llm/config/model_config.py +143 -0
- aiecs/llm/protocols.py +149 -0
- aiecs/llm/utils/__init__.py +10 -0
- aiecs/llm/utils/validate_config.py +89 -0
- aiecs/main.py +140 -121
- aiecs/scripts/aid/VERSION_MANAGEMENT.md +138 -0
- aiecs/scripts/aid/__init__.py +19 -0
- aiecs/scripts/aid/module_checker.py +499 -0
- aiecs/scripts/aid/version_manager.py +235 -0
- aiecs/scripts/{DEPENDENCY_SYSTEM_SUMMARY.md → dependance_check/DEPENDENCY_SYSTEM_SUMMARY.md} +1 -0
- aiecs/scripts/{README_DEPENDENCY_CHECKER.md → dependance_check/README_DEPENDENCY_CHECKER.md} +1 -0
- aiecs/scripts/dependance_check/__init__.py +15 -0
- aiecs/scripts/dependance_check/dependency_checker.py +1835 -0
- aiecs/scripts/{dependency_fixer.py → dependance_check/dependency_fixer.py} +192 -90
- aiecs/scripts/{download_nlp_data.py → dependance_check/download_nlp_data.py} +203 -71
- aiecs/scripts/dependance_patch/__init__.py +7 -0
- aiecs/scripts/dependance_patch/fix_weasel/__init__.py +11 -0
- aiecs/scripts/{fix_weasel_validator.py → dependance_patch/fix_weasel/fix_weasel_validator.py} +21 -14
- aiecs/scripts/{patch_weasel_library.sh → dependance_patch/fix_weasel/patch_weasel_library.sh} +1 -1
- aiecs/scripts/knowledge_graph/__init__.py +3 -0
- aiecs/scripts/knowledge_graph/run_threshold_experiments.py +212 -0
- aiecs/scripts/migrations/multi_tenancy/README.md +142 -0
- aiecs/scripts/tools_develop/README.md +671 -0
- aiecs/scripts/tools_develop/README_CONFIG_CHECKER.md +273 -0
- aiecs/scripts/tools_develop/TOOLS_CONFIG_GUIDE.md +1287 -0
- aiecs/scripts/tools_develop/TOOL_AUTO_DISCOVERY.md +234 -0
- aiecs/scripts/tools_develop/__init__.py +21 -0
- aiecs/scripts/tools_develop/check_all_tools_config.py +548 -0
- aiecs/scripts/tools_develop/check_type_annotations.py +257 -0
- aiecs/scripts/tools_develop/pre-commit-schema-coverage.sh +66 -0
- aiecs/scripts/tools_develop/schema_coverage.py +511 -0
- aiecs/scripts/tools_develop/validate_tool_schemas.py +475 -0
- aiecs/scripts/tools_develop/verify_executor_config_fix.py +98 -0
- aiecs/scripts/tools_develop/verify_tools.py +352 -0
- aiecs/tasks/__init__.py +0 -1
- aiecs/tasks/worker.py +115 -47
- aiecs/tools/__init__.py +194 -72
- aiecs/tools/apisource/__init__.py +99 -0
- aiecs/tools/apisource/intelligence/__init__.py +19 -0
- aiecs/tools/apisource/intelligence/data_fusion.py +632 -0
- aiecs/tools/apisource/intelligence/query_analyzer.py +417 -0
- aiecs/tools/apisource/intelligence/search_enhancer.py +385 -0
- aiecs/tools/apisource/monitoring/__init__.py +9 -0
- aiecs/tools/apisource/monitoring/metrics.py +330 -0
- aiecs/tools/apisource/providers/__init__.py +112 -0
- aiecs/tools/apisource/providers/base.py +671 -0
- aiecs/tools/apisource/providers/census.py +397 -0
- aiecs/tools/apisource/providers/fred.py +535 -0
- aiecs/tools/apisource/providers/newsapi.py +409 -0
- aiecs/tools/apisource/providers/worldbank.py +352 -0
- aiecs/tools/apisource/reliability/__init__.py +12 -0
- aiecs/tools/apisource/reliability/error_handler.py +363 -0
- aiecs/tools/apisource/reliability/fallback_strategy.py +376 -0
- aiecs/tools/apisource/tool.py +832 -0
- aiecs/tools/apisource/utils/__init__.py +9 -0
- aiecs/tools/apisource/utils/validators.py +334 -0
- aiecs/tools/base_tool.py +415 -21
- aiecs/tools/docs/__init__.py +121 -0
- aiecs/tools/docs/ai_document_orchestrator.py +607 -0
- aiecs/tools/docs/ai_document_writer_orchestrator.py +2350 -0
- aiecs/tools/docs/content_insertion_tool.py +1320 -0
- aiecs/tools/docs/document_creator_tool.py +1323 -0
- aiecs/tools/docs/document_layout_tool.py +1160 -0
- aiecs/tools/docs/document_parser_tool.py +1011 -0
- aiecs/tools/docs/document_writer_tool.py +1829 -0
- aiecs/tools/knowledge_graph/__init__.py +17 -0
- aiecs/tools/knowledge_graph/graph_reasoning_tool.py +807 -0
- aiecs/tools/knowledge_graph/graph_search_tool.py +944 -0
- aiecs/tools/knowledge_graph/kg_builder_tool.py +524 -0
- aiecs/tools/langchain_adapter.py +300 -138
- aiecs/tools/schema_generator.py +455 -0
- aiecs/tools/search_tool/__init__.py +100 -0
- aiecs/tools/search_tool/analyzers.py +581 -0
- aiecs/tools/search_tool/cache.py +264 -0
- aiecs/tools/search_tool/constants.py +128 -0
- aiecs/tools/search_tool/context.py +224 -0
- aiecs/tools/search_tool/core.py +778 -0
- aiecs/tools/search_tool/deduplicator.py +119 -0
- aiecs/tools/search_tool/error_handler.py +242 -0
- aiecs/tools/search_tool/metrics.py +343 -0
- aiecs/tools/search_tool/rate_limiter.py +172 -0
- aiecs/tools/search_tool/schemas.py +275 -0
- aiecs/tools/statistics/__init__.py +80 -0
- aiecs/tools/statistics/ai_data_analysis_orchestrator.py +646 -0
- aiecs/tools/statistics/ai_insight_generator_tool.py +508 -0
- aiecs/tools/statistics/ai_report_orchestrator_tool.py +684 -0
- aiecs/tools/statistics/data_loader_tool.py +555 -0
- aiecs/tools/statistics/data_profiler_tool.py +638 -0
- aiecs/tools/statistics/data_transformer_tool.py +580 -0
- aiecs/tools/statistics/data_visualizer_tool.py +498 -0
- aiecs/tools/statistics/model_trainer_tool.py +507 -0
- aiecs/tools/statistics/statistical_analyzer_tool.py +472 -0
- aiecs/tools/task_tools/__init__.py +49 -36
- aiecs/tools/task_tools/chart_tool.py +200 -184
- aiecs/tools/task_tools/classfire_tool.py +268 -267
- aiecs/tools/task_tools/image_tool.py +175 -131
- aiecs/tools/task_tools/office_tool.py +226 -146
- aiecs/tools/task_tools/pandas_tool.py +477 -121
- aiecs/tools/task_tools/report_tool.py +390 -142
- aiecs/tools/task_tools/research_tool.py +149 -79
- aiecs/tools/task_tools/scraper_tool.py +339 -145
- aiecs/tools/task_tools/stats_tool.py +448 -209
- aiecs/tools/temp_file_manager.py +26 -24
- aiecs/tools/tool_executor/__init__.py +18 -16
- aiecs/tools/tool_executor/tool_executor.py +364 -52
- aiecs/utils/LLM_output_structor.py +74 -48
- aiecs/utils/__init__.py +14 -3
- aiecs/utils/base_callback.py +0 -3
- aiecs/utils/cache_provider.py +696 -0
- aiecs/utils/execution_utils.py +50 -31
- aiecs/utils/prompt_loader.py +1 -0
- aiecs/utils/token_usage_repository.py +37 -11
- aiecs/ws/socket_server.py +14 -4
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/METADATA +52 -15
- aiecs-1.7.6.dist-info/RECORD +337 -0
- aiecs-1.7.6.dist-info/entry_points.txt +13 -0
- aiecs/config/registry.py +0 -19
- aiecs/domain/context/content_engine.py +0 -982
- aiecs/llm/base_client.py +0 -99
- aiecs/llm/openai_client.py +0 -125
- aiecs/llm/vertex_client.py +0 -186
- aiecs/llm/xai_client.py +0 -184
- aiecs/scripts/dependency_checker.py +0 -857
- aiecs/scripts/quick_dependency_check.py +0 -269
- aiecs/tools/task_tools/search_api.py +0 -7
- aiecs-1.0.1.dist-info/RECORD +0 -90
- aiecs-1.0.1.dist-info/entry_points.txt +0 -7
- /aiecs/scripts/{setup_nlp_data.sh → dependance_check/setup_nlp_data.sh} +0 -0
- /aiecs/scripts/{README_WEASEL_PATCH.md → dependance_patch/fix_weasel/README_WEASEL_PATCH.md} +0 -0
- /aiecs/scripts/{fix_weasel_validator.sh → dependance_patch/fix_weasel/fix_weasel_validator.sh} +0 -0
- /aiecs/scripts/{run_weasel_patch.sh → dependance_patch/fix_weasel/run_weasel_patch.sh} +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/WHEEL +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type Enums
|
|
3
|
+
|
|
4
|
+
Dynamic enum generation for entity and relation types from schema.
|
|
5
|
+
|
|
6
|
+
Phase: 3.4 - Type Enums
|
|
7
|
+
Version: 1.0
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Type, Dict
|
|
12
|
+
from aiecs.domain.knowledge_graph.schema.graph_schema import GraphSchema
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EntityTypeEnum(str, Enum):
|
|
16
|
+
"""
|
|
17
|
+
Base class for entity type enums
|
|
18
|
+
|
|
19
|
+
Dynamically generated enums inherit from this class.
|
|
20
|
+
Enums are string-based for backward compatibility.
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> PersonType = EntityTypeEnum("PersonType", {"PERSON": "Person"})
|
|
24
|
+
>>> PersonType.PERSON
|
|
25
|
+
'Person'
|
|
26
|
+
>>> str(PersonType.PERSON)
|
|
27
|
+
'Person'
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __str__(self) -> str:
|
|
31
|
+
"""Return the enum value (for backward compatibility)"""
|
|
32
|
+
return self.value
|
|
33
|
+
|
|
34
|
+
def __repr__(self) -> str:
|
|
35
|
+
"""Return the enum representation"""
|
|
36
|
+
return f"{self.__class__.__name__}.{self.name}"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class RelationTypeEnum(str, Enum):
|
|
40
|
+
"""
|
|
41
|
+
Base class for relation type enums
|
|
42
|
+
|
|
43
|
+
Dynamically generated enums inherit from this class.
|
|
44
|
+
Enums are string-based for backward compatibility.
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
>>> WorksForType = RelationTypeEnum("WorksForType", {"WORKS_FOR": "WORKS_FOR"})
|
|
48
|
+
>>> WorksForType.WORKS_FOR
|
|
49
|
+
'WORKS_FOR'
|
|
50
|
+
>>> str(WorksForType.WORKS_FOR)
|
|
51
|
+
'WORKS_FOR'
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __str__(self) -> str:
|
|
55
|
+
"""Return the enum value (for backward compatibility)"""
|
|
56
|
+
return self.value
|
|
57
|
+
|
|
58
|
+
def __repr__(self) -> str:
|
|
59
|
+
"""Return the enum representation"""
|
|
60
|
+
return f"{self.__class__.__name__}.{self.name}"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TypeEnumGenerator:
|
|
64
|
+
"""
|
|
65
|
+
Utility for generating type enums from schema
|
|
66
|
+
|
|
67
|
+
Generates Python Enum classes for entity types and relation types
|
|
68
|
+
defined in a GraphSchema. The generated enums are string-based for
|
|
69
|
+
backward compatibility with existing code that uses string literals.
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
>>> generator = TypeEnumGenerator(schema)
|
|
73
|
+
>>> entity_enums = generator.generate_entity_type_enums()
|
|
74
|
+
>>> relation_enums = generator.generate_relation_type_enums()
|
|
75
|
+
>>>
|
|
76
|
+
>>> # Use generated enums
|
|
77
|
+
>>> PersonType = entity_enums["Person"]
|
|
78
|
+
>>> person_type = PersonType.PERSON # "Person"
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
def __init__(self, schema: GraphSchema):
|
|
82
|
+
"""
|
|
83
|
+
Initialize enum generator
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
schema: Graph schema to generate enums from
|
|
87
|
+
"""
|
|
88
|
+
self.schema = schema
|
|
89
|
+
|
|
90
|
+
def generate_entity_type_enums(self) -> Dict[str, Type[EntityTypeEnum]]:
|
|
91
|
+
"""
|
|
92
|
+
Generate entity type enums from schema
|
|
93
|
+
|
|
94
|
+
Creates an enum class for each entity type in the schema.
|
|
95
|
+
The enum name is the entity type name, and the enum value
|
|
96
|
+
is also the entity type name (for backward compatibility).
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Dictionary mapping entity type names to enum classes
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
>>> enums = generator.generate_entity_type_enums()
|
|
103
|
+
>>> PersonEnum = enums["Person"]
|
|
104
|
+
>>> PersonEnum.PERSON # "Person"
|
|
105
|
+
"""
|
|
106
|
+
enums = {}
|
|
107
|
+
|
|
108
|
+
for entity_type_name in self.schema.get_entity_type_names():
|
|
109
|
+
# Create enum name (convert to uppercase with underscores)
|
|
110
|
+
enum_member_name = self._to_enum_name(entity_type_name)
|
|
111
|
+
|
|
112
|
+
# Create enum class dynamically using type()
|
|
113
|
+
enum_class = type(
|
|
114
|
+
entity_type_name + "Enum",
|
|
115
|
+
(EntityTypeEnum,),
|
|
116
|
+
{enum_member_name: entity_type_name}
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
enums[entity_type_name] = enum_class
|
|
120
|
+
|
|
121
|
+
return enums
|
|
122
|
+
|
|
123
|
+
def generate_relation_type_enums(
|
|
124
|
+
self,
|
|
125
|
+
) -> Dict[str, Type[RelationTypeEnum]]:
|
|
126
|
+
"""
|
|
127
|
+
Generate relation type enums from schema
|
|
128
|
+
|
|
129
|
+
Creates an enum class for each relation type in the schema.
|
|
130
|
+
The enum name is the relation type name, and the enum value
|
|
131
|
+
is also the relation type name (for backward compatibility).
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Dictionary mapping relation type names to enum classes
|
|
135
|
+
|
|
136
|
+
Example:
|
|
137
|
+
>>> enums = generator.generate_relation_type_enums()
|
|
138
|
+
>>> WorksForEnum = enums["WORKS_FOR"]
|
|
139
|
+
>>> WorksForEnum.WORKS_FOR # "WORKS_FOR"
|
|
140
|
+
"""
|
|
141
|
+
enums = {}
|
|
142
|
+
|
|
143
|
+
for relation_type_name in self.schema.get_relation_type_names():
|
|
144
|
+
# Create enum name (convert to uppercase with underscores)
|
|
145
|
+
enum_member_name = self._to_enum_name(relation_type_name)
|
|
146
|
+
|
|
147
|
+
# Create enum class dynamically using type()
|
|
148
|
+
enum_class = type(
|
|
149
|
+
relation_type_name + "Enum",
|
|
150
|
+
(RelationTypeEnum,),
|
|
151
|
+
{enum_member_name: relation_type_name}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
enums[relation_type_name] = enum_class
|
|
155
|
+
|
|
156
|
+
return enums
|
|
157
|
+
|
|
158
|
+
def generate_all_enums(self) -> Dict[str, Dict[str, Type[Enum]]]:
|
|
159
|
+
"""
|
|
160
|
+
Generate all type enums from schema
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Dictionary with "entity_types" and "relation_types" keys,
|
|
164
|
+
each containing a dictionary of enum classes
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
>>> enums = generator.generate_all_enums()
|
|
168
|
+
>>> PersonEnum = enums["entity_types"]["Person"]
|
|
169
|
+
>>> WorksForEnum = enums["relation_types"]["WORKS_FOR"]
|
|
170
|
+
"""
|
|
171
|
+
from typing import cast
|
|
172
|
+
return {
|
|
173
|
+
"entity_types": cast(Dict[str, Type[Enum]], self.generate_entity_type_enums()),
|
|
174
|
+
"relation_types": cast(Dict[str, Type[Enum]], self.generate_relation_type_enums()),
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def _to_enum_name(type_name: str) -> str:
|
|
179
|
+
"""
|
|
180
|
+
Convert type name to enum member name
|
|
181
|
+
|
|
182
|
+
Converts CamelCase or snake_case to UPPER_CASE.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
type_name: Type name to convert
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Enum member name in UPPER_CASE
|
|
189
|
+
|
|
190
|
+
Example:
|
|
191
|
+
>>> TypeEnumGenerator._to_enum_name("Person")
|
|
192
|
+
'PERSON'
|
|
193
|
+
>>> TypeEnumGenerator._to_enum_name("WorksFor")
|
|
194
|
+
'WORKS_FOR'
|
|
195
|
+
>>> TypeEnumGenerator._to_enum_name("WORKS_FOR")
|
|
196
|
+
'WORKS_FOR'
|
|
197
|
+
"""
|
|
198
|
+
# If already uppercase, return as-is
|
|
199
|
+
if type_name.isupper():
|
|
200
|
+
return type_name
|
|
201
|
+
|
|
202
|
+
# Convert CamelCase to UPPER_CASE
|
|
203
|
+
result = []
|
|
204
|
+
for i, char in enumerate(type_name):
|
|
205
|
+
if char.isupper() and i > 0 and type_name[i - 1].islower():
|
|
206
|
+
result.append("_")
|
|
207
|
+
result.append(char.upper())
|
|
208
|
+
|
|
209
|
+
return "".join(result)
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
-
import
|
|
5
|
-
from typing import Dict, List, Any, Optional, Callable
|
|
4
|
+
from typing import Dict, List, Any, Callable, Optional
|
|
6
5
|
from aiecs.domain.execution.model import TaskStepResult, TaskStatus, ErrorCode
|
|
7
6
|
|
|
8
7
|
logger = logging.getLogger(__name__)
|
|
@@ -20,21 +19,26 @@ class DSLProcessor:
|
|
|
20
19
|
r"intent\.includes\('([^']+)'\)",
|
|
21
20
|
r"context\.(\w+)\s*(==|!=|>|<|>=|<=)\s*(.+)",
|
|
22
21
|
r"input\.(\w+)\s*(==|!=|>|<|>=|<=)\s*(.+)",
|
|
23
|
-
r"result\[(\d+)\]\.(\w+)\s*(==|!=|>|<|>=|<=)\s*(.+)"
|
|
22
|
+
r"result\[(\d+)\]\.(\w+)\s*(==|!=|>|<|>=|<=)\s*(.+)",
|
|
24
23
|
]
|
|
25
24
|
# Condition check priority order
|
|
26
25
|
self.condition_check_order = [
|
|
27
26
|
"AND", # Logical AND operation
|
|
28
|
-
"OR",
|
|
27
|
+
"OR", # Logical OR operation
|
|
29
28
|
"intent.includes", # Intent inclusion check
|
|
30
29
|
"context", # Context check
|
|
31
|
-
"input",
|
|
32
|
-
"result"
|
|
30
|
+
"input", # Input check
|
|
31
|
+
"result", # Result check
|
|
33
32
|
]
|
|
34
33
|
|
|
35
|
-
def evaluate_condition(
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
def evaluate_condition(
|
|
35
|
+
self,
|
|
36
|
+
condition: str,
|
|
37
|
+
intent_categories: List[str],
|
|
38
|
+
context: Optional[Dict[str, Any]] = None,
|
|
39
|
+
input_data: Optional[Dict[str, Any]] = None,
|
|
40
|
+
results: Optional[List[TaskStepResult]] = None,
|
|
41
|
+
) -> bool:
|
|
38
42
|
"""
|
|
39
43
|
Evaluate condition expression, supporting multiple condition types
|
|
40
44
|
Following optimized check order: AND -> OR -> intent.includes -> context -> input -> result
|
|
@@ -43,12 +47,30 @@ class DSLProcessor:
|
|
|
43
47
|
# 1. Compound condition: support AND (highest priority)
|
|
44
48
|
if " AND " in condition:
|
|
45
49
|
parts = condition.split(" AND ")
|
|
46
|
-
return all(
|
|
50
|
+
return all(
|
|
51
|
+
self.evaluate_condition(
|
|
52
|
+
part.strip(),
|
|
53
|
+
intent_categories,
|
|
54
|
+
context,
|
|
55
|
+
input_data,
|
|
56
|
+
results,
|
|
57
|
+
)
|
|
58
|
+
for part in parts
|
|
59
|
+
)
|
|
47
60
|
|
|
48
61
|
# 2. Compound condition: support OR (second priority)
|
|
49
62
|
if " OR " in condition:
|
|
50
63
|
parts = condition.split(" OR ")
|
|
51
|
-
return any(
|
|
64
|
+
return any(
|
|
65
|
+
self.evaluate_condition(
|
|
66
|
+
part.strip(),
|
|
67
|
+
intent_categories,
|
|
68
|
+
context,
|
|
69
|
+
input_data,
|
|
70
|
+
results,
|
|
71
|
+
)
|
|
72
|
+
for part in parts
|
|
73
|
+
)
|
|
52
74
|
|
|
53
75
|
# 3. Intent condition: intent.includes('category')
|
|
54
76
|
match = re.fullmatch(r"intent\.includes\('([^']+)'\)", condition)
|
|
@@ -152,9 +174,16 @@ class DSLProcessor:
|
|
|
152
174
|
|
|
153
175
|
return False
|
|
154
176
|
|
|
155
|
-
async def execute_dsl_step(
|
|
156
|
-
|
|
157
|
-
|
|
177
|
+
async def execute_dsl_step(
|
|
178
|
+
self,
|
|
179
|
+
step: Dict,
|
|
180
|
+
intent_categories: List[str],
|
|
181
|
+
input_data: Dict,
|
|
182
|
+
context: Dict,
|
|
183
|
+
execute_single_task: Callable,
|
|
184
|
+
execute_batch_task: Callable,
|
|
185
|
+
results: Optional[List[TaskStepResult]] = None,
|
|
186
|
+
) -> TaskStepResult:
|
|
158
187
|
"""
|
|
159
188
|
Execute DSL step based on step type (if, parallel, task, sequence)
|
|
160
189
|
"""
|
|
@@ -164,18 +193,42 @@ class DSLProcessor:
|
|
|
164
193
|
|
|
165
194
|
try:
|
|
166
195
|
if "if" in step:
|
|
167
|
-
return await self._handle_if_step(
|
|
168
|
-
|
|
196
|
+
return await self._handle_if_step(
|
|
197
|
+
step,
|
|
198
|
+
intent_categories,
|
|
199
|
+
input_data,
|
|
200
|
+
context,
|
|
201
|
+
execute_single_task,
|
|
202
|
+
execute_batch_task,
|
|
203
|
+
span,
|
|
204
|
+
results,
|
|
205
|
+
)
|
|
169
206
|
elif "parallel" in step:
|
|
170
207
|
return await self._handle_parallel_step(step, input_data, context, execute_batch_task, span)
|
|
171
208
|
elif "sequence" in step:
|
|
172
|
-
return await self._handle_sequence_step(
|
|
173
|
-
|
|
209
|
+
return await self._handle_sequence_step(
|
|
210
|
+
step,
|
|
211
|
+
intent_categories,
|
|
212
|
+
input_data,
|
|
213
|
+
context,
|
|
214
|
+
execute_single_task,
|
|
215
|
+
execute_batch_task,
|
|
216
|
+
span,
|
|
217
|
+
results,
|
|
218
|
+
)
|
|
174
219
|
elif "task" in step:
|
|
175
220
|
return await self._handle_task_step(step, input_data, context, execute_single_task, span)
|
|
176
221
|
elif "loop" in step:
|
|
177
|
-
return await self._handle_loop_step(
|
|
178
|
-
|
|
222
|
+
return await self._handle_loop_step(
|
|
223
|
+
step,
|
|
224
|
+
intent_categories,
|
|
225
|
+
input_data,
|
|
226
|
+
context,
|
|
227
|
+
execute_single_task,
|
|
228
|
+
execute_batch_task,
|
|
229
|
+
span,
|
|
230
|
+
results,
|
|
231
|
+
)
|
|
179
232
|
else:
|
|
180
233
|
if span:
|
|
181
234
|
span.set_tag("error", True)
|
|
@@ -187,15 +240,23 @@ class DSLProcessor:
|
|
|
187
240
|
message="Invalid DSL step",
|
|
188
241
|
status=TaskStatus.FAILED.value,
|
|
189
242
|
error_code=ErrorCode.EXECUTION_ERROR.value,
|
|
190
|
-
error_message="Unknown DSL step type"
|
|
243
|
+
error_message="Unknown DSL step type",
|
|
191
244
|
)
|
|
192
245
|
finally:
|
|
193
246
|
if span:
|
|
194
247
|
span.finish()
|
|
195
248
|
|
|
196
|
-
async def _handle_if_step(
|
|
197
|
-
|
|
198
|
-
|
|
249
|
+
async def _handle_if_step(
|
|
250
|
+
self,
|
|
251
|
+
step: Dict,
|
|
252
|
+
intent_categories: List[str],
|
|
253
|
+
input_data: Dict,
|
|
254
|
+
context: Dict,
|
|
255
|
+
execute_single_task: Callable,
|
|
256
|
+
execute_batch_task: Callable,
|
|
257
|
+
span=None,
|
|
258
|
+
results: Optional[List[TaskStepResult]] = None,
|
|
259
|
+
) -> TaskStepResult:
|
|
199
260
|
"""Handle conditional 'if' step"""
|
|
200
261
|
condition = step["if"]
|
|
201
262
|
then_steps = step["then"]
|
|
@@ -213,8 +274,15 @@ class DSLProcessor:
|
|
|
213
274
|
|
|
214
275
|
step_results = []
|
|
215
276
|
for sub_step in then_steps:
|
|
216
|
-
result = await self.execute_dsl_step(
|
|
217
|
-
|
|
277
|
+
result = await self.execute_dsl_step(
|
|
278
|
+
sub_step,
|
|
279
|
+
intent_categories,
|
|
280
|
+
input_data,
|
|
281
|
+
context,
|
|
282
|
+
execute_single_task,
|
|
283
|
+
execute_batch_task,
|
|
284
|
+
results,
|
|
285
|
+
)
|
|
218
286
|
step_results.append(result)
|
|
219
287
|
if results is not None:
|
|
220
288
|
results.append(result)
|
|
@@ -224,7 +292,7 @@ class DSLProcessor:
|
|
|
224
292
|
result=[r.dict() for r in step_results],
|
|
225
293
|
completed=all(r.completed for r in step_results),
|
|
226
294
|
message=f"Condition '{condition}' evaluated to true",
|
|
227
|
-
status=TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value
|
|
295
|
+
status=(TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value),
|
|
228
296
|
)
|
|
229
297
|
else:
|
|
230
298
|
if span:
|
|
@@ -233,8 +301,15 @@ class DSLProcessor:
|
|
|
233
301
|
if else_steps:
|
|
234
302
|
step_results = []
|
|
235
303
|
for sub_step in else_steps:
|
|
236
|
-
result = await self.execute_dsl_step(
|
|
237
|
-
|
|
304
|
+
result = await self.execute_dsl_step(
|
|
305
|
+
sub_step,
|
|
306
|
+
intent_categories,
|
|
307
|
+
input_data,
|
|
308
|
+
context,
|
|
309
|
+
execute_single_task,
|
|
310
|
+
execute_batch_task,
|
|
311
|
+
results,
|
|
312
|
+
)
|
|
238
313
|
step_results.append(result)
|
|
239
314
|
if results is not None:
|
|
240
315
|
results.append(result)
|
|
@@ -244,7 +319,7 @@ class DSLProcessor:
|
|
|
244
319
|
result=[r.dict() for r in step_results],
|
|
245
320
|
completed=all(r.completed for r in step_results),
|
|
246
321
|
message=f"Condition '{condition}' evaluated to false, executed else branch",
|
|
247
|
-
status=TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value
|
|
322
|
+
status=(TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value),
|
|
248
323
|
)
|
|
249
324
|
else:
|
|
250
325
|
return TaskStepResult(
|
|
@@ -252,7 +327,7 @@ class DSLProcessor:
|
|
|
252
327
|
result=None,
|
|
253
328
|
completed=True,
|
|
254
329
|
message=f"Condition '{condition}' evaluated to false, skipping",
|
|
255
|
-
status=TaskStatus.COMPLETED.value
|
|
330
|
+
status=TaskStatus.COMPLETED.value,
|
|
256
331
|
)
|
|
257
332
|
except Exception as e:
|
|
258
333
|
if span:
|
|
@@ -265,11 +340,17 @@ class DSLProcessor:
|
|
|
265
340
|
message="Failed to evaluate condition",
|
|
266
341
|
status=TaskStatus.FAILED.value,
|
|
267
342
|
error_code=ErrorCode.DSL_EVALUATION_ERROR.value,
|
|
268
|
-
error_message=str(e)
|
|
343
|
+
error_message=str(e),
|
|
269
344
|
)
|
|
270
345
|
|
|
271
|
-
async def _handle_parallel_step(
|
|
272
|
-
|
|
346
|
+
async def _handle_parallel_step(
|
|
347
|
+
self,
|
|
348
|
+
step: Dict,
|
|
349
|
+
input_data: Dict,
|
|
350
|
+
context: Dict,
|
|
351
|
+
execute_batch_task: Callable,
|
|
352
|
+
span=None,
|
|
353
|
+
) -> TaskStepResult:
|
|
273
354
|
"""Handle parallel task execution"""
|
|
274
355
|
task_names = step["parallel"]
|
|
275
356
|
if span:
|
|
@@ -283,12 +364,20 @@ class DSLProcessor:
|
|
|
283
364
|
result=[r.dict() for r in batch_results],
|
|
284
365
|
completed=all(r.completed for r in batch_results),
|
|
285
366
|
message=f"Completed parallel execution of {len(task_names)} tasks",
|
|
286
|
-
status=TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in batch_results) else TaskStatus.FAILED.value
|
|
367
|
+
status=(TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in batch_results) else TaskStatus.FAILED.value),
|
|
287
368
|
)
|
|
288
369
|
|
|
289
|
-
async def _handle_sequence_step(
|
|
290
|
-
|
|
291
|
-
|
|
370
|
+
async def _handle_sequence_step(
|
|
371
|
+
self,
|
|
372
|
+
step: Dict,
|
|
373
|
+
intent_categories: List[str],
|
|
374
|
+
input_data: Dict,
|
|
375
|
+
context: Dict,
|
|
376
|
+
execute_single_task: Callable,
|
|
377
|
+
execute_batch_task: Callable,
|
|
378
|
+
span=None,
|
|
379
|
+
results: Optional[List[TaskStepResult]] = None,
|
|
380
|
+
) -> TaskStepResult:
|
|
292
381
|
"""Handle sequential execution steps"""
|
|
293
382
|
sequence_steps = step["sequence"]
|
|
294
383
|
if span:
|
|
@@ -296,8 +385,15 @@ class DSLProcessor:
|
|
|
296
385
|
|
|
297
386
|
step_results = []
|
|
298
387
|
for i, sub_step in enumerate(sequence_steps):
|
|
299
|
-
result = await self.execute_dsl_step(
|
|
300
|
-
|
|
388
|
+
result = await self.execute_dsl_step(
|
|
389
|
+
sub_step,
|
|
390
|
+
intent_categories,
|
|
391
|
+
input_data,
|
|
392
|
+
context,
|
|
393
|
+
execute_single_task,
|
|
394
|
+
execute_batch_task,
|
|
395
|
+
results,
|
|
396
|
+
)
|
|
301
397
|
step_results.append(result)
|
|
302
398
|
if results is not None:
|
|
303
399
|
results.append(result)
|
|
@@ -311,11 +407,17 @@ class DSLProcessor:
|
|
|
311
407
|
result=[r.dict() for r in step_results],
|
|
312
408
|
completed=all(r.completed for r in step_results),
|
|
313
409
|
message=f"Completed sequence execution of {len(step_results)} steps",
|
|
314
|
-
status=TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value
|
|
410
|
+
status=(TaskStatus.COMPLETED.value if all(r.status == TaskStatus.COMPLETED.value for r in step_results) else TaskStatus.FAILED.value),
|
|
315
411
|
)
|
|
316
412
|
|
|
317
|
-
async def _handle_task_step(
|
|
318
|
-
|
|
413
|
+
async def _handle_task_step(
|
|
414
|
+
self,
|
|
415
|
+
step: Dict,
|
|
416
|
+
input_data: Dict,
|
|
417
|
+
context: Dict,
|
|
418
|
+
execute_single_task: Callable,
|
|
419
|
+
span=None,
|
|
420
|
+
) -> TaskStepResult:
|
|
319
421
|
"""Handle single task execution"""
|
|
320
422
|
task_name = step["task"]
|
|
321
423
|
task_params = step.get("params", {})
|
|
@@ -336,7 +438,7 @@ class DSLProcessor:
|
|
|
336
438
|
result=result,
|
|
337
439
|
completed=True,
|
|
338
440
|
message=f"Completed task {task_name}",
|
|
339
|
-
status=TaskStatus.COMPLETED.value
|
|
441
|
+
status=TaskStatus.COMPLETED.value,
|
|
340
442
|
)
|
|
341
443
|
except Exception as e:
|
|
342
444
|
if span:
|
|
@@ -349,12 +451,20 @@ class DSLProcessor:
|
|
|
349
451
|
message=f"Failed to execute task {task_name}",
|
|
350
452
|
status=TaskStatus.FAILED.value,
|
|
351
453
|
error_code=ErrorCode.EXECUTION_ERROR.value,
|
|
352
|
-
error_message=str(e)
|
|
454
|
+
error_message=str(e),
|
|
353
455
|
)
|
|
354
456
|
|
|
355
|
-
async def _handle_loop_step(
|
|
356
|
-
|
|
357
|
-
|
|
457
|
+
async def _handle_loop_step(
|
|
458
|
+
self,
|
|
459
|
+
step: Dict,
|
|
460
|
+
intent_categories: List[str],
|
|
461
|
+
input_data: Dict,
|
|
462
|
+
context: Dict,
|
|
463
|
+
execute_single_task: Callable,
|
|
464
|
+
execute_batch_task: Callable,
|
|
465
|
+
span=None,
|
|
466
|
+
results: Optional[List[TaskStepResult]] = None,
|
|
467
|
+
) -> TaskStepResult:
|
|
358
468
|
"""Handle loop step"""
|
|
359
469
|
loop_config = step["loop"]
|
|
360
470
|
loop_steps = loop_config["steps"]
|
|
@@ -376,8 +486,15 @@ class DSLProcessor:
|
|
|
376
486
|
# Execute loop body
|
|
377
487
|
iteration_step_results = []
|
|
378
488
|
for sub_step in loop_steps:
|
|
379
|
-
result = await self.execute_dsl_step(
|
|
380
|
-
|
|
489
|
+
result = await self.execute_dsl_step(
|
|
490
|
+
sub_step,
|
|
491
|
+
intent_categories,
|
|
492
|
+
input_data,
|
|
493
|
+
context,
|
|
494
|
+
execute_single_task,
|
|
495
|
+
execute_batch_task,
|
|
496
|
+
results,
|
|
497
|
+
)
|
|
381
498
|
iteration_step_results.append(result)
|
|
382
499
|
if results is not None:
|
|
383
500
|
results.append(result)
|
|
@@ -391,11 +508,10 @@ class DSLProcessor:
|
|
|
391
508
|
|
|
392
509
|
return TaskStepResult(
|
|
393
510
|
step=f"loop_{iteration}_iterations",
|
|
394
|
-
result=[{"iteration": i, "results": [r.dict() for r in iter_results]}
|
|
395
|
-
for i, iter_results in enumerate(iteration_results)],
|
|
511
|
+
result=[{"iteration": i, "results": [r.dict() for r in iter_results]} for i, iter_results in enumerate(iteration_results)],
|
|
396
512
|
completed=True,
|
|
397
513
|
message=f"Completed loop with {iteration} iterations",
|
|
398
|
-
status=TaskStatus.COMPLETED.value
|
|
514
|
+
status=TaskStatus.COMPLETED.value,
|
|
399
515
|
)
|
|
400
516
|
|
|
401
517
|
def validate_dsl_step(self, step: Dict) -> List[str]:
|
|
@@ -444,7 +560,7 @@ class DSLProcessor:
|
|
|
444
560
|
"intent.includes('category')",
|
|
445
561
|
"context.field == value",
|
|
446
562
|
"input.field == value",
|
|
447
|
-
"result[index].field == value"
|
|
563
|
+
"result[index].field == value",
|
|
448
564
|
],
|
|
449
565
|
"operators": ["==", "!=", ">", "<", ">=", "<="],
|
|
450
566
|
"logical_operators": ["AND", "OR"],
|
|
@@ -455,6 +571,6 @@ class DSLProcessor:
|
|
|
455
571
|
"Use re.fullmatch instead of re.match for stricter matching",
|
|
456
572
|
"Optimize condition check order: AND -> OR -> intent.includes -> context -> input -> result",
|
|
457
573
|
"Enhance value parsing robustness, support null values",
|
|
458
|
-
"Add condition syntax validation method"
|
|
459
|
-
]
|
|
574
|
+
"Add condition syntax validation method",
|
|
575
|
+
],
|
|
460
576
|
}
|
aiecs/domain/task/model.py
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
from typing import Any, Dict,
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class TaskContext:
|
|
6
6
|
"""Task context model"""
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
user_id: str,
|
|
11
|
+
task_id: str,
|
|
12
|
+
session_id: Optional[str] = None,
|
|
13
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
14
|
+
):
|
|
9
15
|
self.user_id = user_id
|
|
10
16
|
self.task_id = task_id
|
|
11
17
|
self.session_id = session_id
|
|
12
18
|
self.metadata = metadata or {}
|
|
13
19
|
self.created_at = datetime.now()
|
|
14
|
-
self.variables = {} # Variable storage during task execution
|
|
20
|
+
self.variables: Dict[str, Any] = {} # Variable storage during task execution
|
|
15
21
|
|
|
16
22
|
def set_variable(self, key: str, value: Any):
|
|
17
23
|
"""Set task variable"""
|
|
@@ -28,14 +34,20 @@ class TaskContext:
|
|
|
28
34
|
"session_id": self.session_id,
|
|
29
35
|
"metadata": self.metadata,
|
|
30
36
|
"created_at": self.created_at.isoformat(),
|
|
31
|
-
"variables": self.variables
|
|
37
|
+
"variables": self.variables,
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
class DSLStep:
|
|
36
42
|
"""DSL step model"""
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
step_type: str,
|
|
47
|
+
condition: Optional[str] = None,
|
|
48
|
+
description: str = "",
|
|
49
|
+
params: Optional[Dict[str, Any]] = None,
|
|
50
|
+
):
|
|
39
51
|
self.step_type = step_type
|
|
40
52
|
self.condition = condition
|
|
41
53
|
self.description = description
|
|
@@ -46,5 +58,5 @@ class DSLStep:
|
|
|
46
58
|
"step_type": self.step_type,
|
|
47
59
|
"condition": self.condition,
|
|
48
60
|
"description": self.description,
|
|
49
|
-
"params": self.params
|
|
61
|
+
"params": self.params,
|
|
50
62
|
}
|