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,354 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Conversation Models for ContextEngine
|
|
3
|
+
|
|
4
|
+
This module defines the data models used for agent communication and conversation isolation
|
|
5
|
+
within the ContextEngine. These models are specific to the context management domain.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import uuid
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Dict, List, Any, Optional
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class ConversationParticipant:
|
|
16
|
+
"""Represents a participant in a conversation."""
|
|
17
|
+
|
|
18
|
+
participant_id: str
|
|
19
|
+
participant_type: str # 'user', 'master_controller', 'agent'
|
|
20
|
+
# For agents: 'writer', 'researcher', etc.
|
|
21
|
+
participant_role: Optional[str] = None
|
|
22
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
23
|
+
|
|
24
|
+
def __post_init__(self):
|
|
25
|
+
"""Validate participant data after initialization."""
|
|
26
|
+
if not self.participant_id:
|
|
27
|
+
raise ValueError("participant_id cannot be empty")
|
|
28
|
+
if not self.participant_type:
|
|
29
|
+
raise ValueError("participant_type cannot be empty")
|
|
30
|
+
|
|
31
|
+
# Validate participant types
|
|
32
|
+
valid_types = {"user", "master_controller", "agent"}
|
|
33
|
+
if self.participant_type not in valid_types:
|
|
34
|
+
raise ValueError(f"participant_type must be one of {valid_types}")
|
|
35
|
+
|
|
36
|
+
# For agents, role should be specified
|
|
37
|
+
if self.participant_type == "agent" and not self.participant_role:
|
|
38
|
+
raise ValueError("participant_role is required for agent participants")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class ConversationSession:
|
|
43
|
+
"""Represents an isolated conversation session between participants."""
|
|
44
|
+
|
|
45
|
+
session_id: str
|
|
46
|
+
participants: List[ConversationParticipant]
|
|
47
|
+
session_type: str # 'user_to_mc', 'mc_to_agent', 'agent_to_agent', 'user_to_agent'
|
|
48
|
+
created_at: datetime
|
|
49
|
+
last_activity: datetime
|
|
50
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
51
|
+
|
|
52
|
+
def __post_init__(self):
|
|
53
|
+
"""Validate session data after initialization."""
|
|
54
|
+
if not self.session_id:
|
|
55
|
+
raise ValueError("session_id cannot be empty")
|
|
56
|
+
if not self.participants:
|
|
57
|
+
raise ValueError("participants list cannot be empty")
|
|
58
|
+
|
|
59
|
+
# Validate session types
|
|
60
|
+
valid_session_types = {
|
|
61
|
+
"user_to_mc",
|
|
62
|
+
"mc_to_agent",
|
|
63
|
+
"agent_to_agent",
|
|
64
|
+
"user_to_agent",
|
|
65
|
+
}
|
|
66
|
+
if self.session_type not in valid_session_types:
|
|
67
|
+
raise ValueError(f"session_type must be one of {valid_session_types}")
|
|
68
|
+
|
|
69
|
+
# Validate participant count and types based on session type
|
|
70
|
+
self._validate_participants_for_session_type()
|
|
71
|
+
|
|
72
|
+
def _validate_participants_for_session_type(self):
|
|
73
|
+
"""Validate that participants match the session type."""
|
|
74
|
+
participant_types = [p.participant_type for p in self.participants]
|
|
75
|
+
|
|
76
|
+
if self.session_type == "user_to_mc":
|
|
77
|
+
expected_types = {"user", "master_controller"}
|
|
78
|
+
if not expected_types.issubset(set(participant_types)):
|
|
79
|
+
raise ValueError(
|
|
80
|
+
"user_to_mc session requires user and master_controller participants"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
elif self.session_type == "mc_to_agent":
|
|
84
|
+
expected_types = {"master_controller", "agent"}
|
|
85
|
+
if not expected_types.issubset(set(participant_types)):
|
|
86
|
+
raise ValueError(
|
|
87
|
+
"mc_to_agent session requires master_controller and agent participants"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
elif self.session_type == "agent_to_agent":
|
|
91
|
+
agent_count = sum(1 for p in self.participants if p.participant_type == "agent")
|
|
92
|
+
if agent_count < 2:
|
|
93
|
+
raise ValueError("agent_to_agent session requires at least 2 agent participants")
|
|
94
|
+
|
|
95
|
+
elif self.session_type == "user_to_agent":
|
|
96
|
+
expected_types = {"user", "agent"}
|
|
97
|
+
if not expected_types.issubset(set(participant_types)):
|
|
98
|
+
raise ValueError("user_to_agent session requires user and agent participants")
|
|
99
|
+
|
|
100
|
+
def generate_session_key(self) -> str:
|
|
101
|
+
"""Generate a unique session key for conversation isolation."""
|
|
102
|
+
if self.session_type == "user_to_mc":
|
|
103
|
+
return self.session_id
|
|
104
|
+
elif self.session_type == "mc_to_agent":
|
|
105
|
+
agent_role = next(
|
|
106
|
+
(p.participant_role for p in self.participants if p.participant_type == "agent"),
|
|
107
|
+
"unknown",
|
|
108
|
+
)
|
|
109
|
+
return f"{self.session_id}_mc_to_{agent_role}"
|
|
110
|
+
elif self.session_type == "agent_to_agent":
|
|
111
|
+
agent_roles = [
|
|
112
|
+
p.participant_role for p in self.participants if p.participant_type == "agent"
|
|
113
|
+
]
|
|
114
|
+
if len(agent_roles) >= 2:
|
|
115
|
+
return f"{self.session_id}_{agent_roles[0]}_to_{agent_roles[1]}"
|
|
116
|
+
return f"{self.session_id}_agent_to_agent"
|
|
117
|
+
elif self.session_type == "user_to_agent":
|
|
118
|
+
agent_role = next(
|
|
119
|
+
(p.participant_role for p in self.participants if p.participant_type == "agent"),
|
|
120
|
+
"unknown",
|
|
121
|
+
)
|
|
122
|
+
return f"{self.session_id}_user_to_{agent_role}"
|
|
123
|
+
else:
|
|
124
|
+
return self.session_id
|
|
125
|
+
|
|
126
|
+
def get_participant_by_type_and_role(
|
|
127
|
+
self, participant_type: str, participant_role: Optional[str] = None
|
|
128
|
+
) -> Optional[ConversationParticipant]:
|
|
129
|
+
"""Get a participant by type and optionally by role."""
|
|
130
|
+
for participant in self.participants:
|
|
131
|
+
if participant.participant_type == participant_type:
|
|
132
|
+
if participant_role is None or participant.participant_role == participant_role:
|
|
133
|
+
return participant
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
def update_activity(self):
|
|
137
|
+
"""Update the last activity timestamp."""
|
|
138
|
+
self.last_activity = datetime.utcnow()
|
|
139
|
+
|
|
140
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
141
|
+
"""Convert to dictionary for storage."""
|
|
142
|
+
return {
|
|
143
|
+
"session_id": self.session_id,
|
|
144
|
+
"participants": [
|
|
145
|
+
{
|
|
146
|
+
"participant_id": p.participant_id,
|
|
147
|
+
"participant_type": p.participant_type,
|
|
148
|
+
"participant_role": p.participant_role,
|
|
149
|
+
"metadata": p.metadata,
|
|
150
|
+
}
|
|
151
|
+
for p in self.participants
|
|
152
|
+
],
|
|
153
|
+
"session_type": self.session_type,
|
|
154
|
+
"created_at": self.created_at.isoformat(),
|
|
155
|
+
"last_activity": self.last_activity.isoformat(),
|
|
156
|
+
"metadata": self.metadata,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@classmethod
|
|
160
|
+
def from_dict(cls, data: Dict[str, Any]) -> "ConversationSession":
|
|
161
|
+
"""Create from dictionary."""
|
|
162
|
+
participants = [
|
|
163
|
+
ConversationParticipant(
|
|
164
|
+
participant_id=p["participant_id"],
|
|
165
|
+
participant_type=p["participant_type"],
|
|
166
|
+
participant_role=p.get("participant_role"),
|
|
167
|
+
metadata=p.get("metadata", {}),
|
|
168
|
+
)
|
|
169
|
+
for p in data["participants"]
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
return cls(
|
|
173
|
+
session_id=data["session_id"],
|
|
174
|
+
participants=participants,
|
|
175
|
+
session_type=data["session_type"],
|
|
176
|
+
created_at=datetime.fromisoformat(data["created_at"]),
|
|
177
|
+
last_activity=datetime.fromisoformat(data["last_activity"]),
|
|
178
|
+
metadata=data.get("metadata", {}),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@dataclass
|
|
183
|
+
class AgentCommunicationMessage:
|
|
184
|
+
"""Message for agent-to-agent or controller-to-agent communication."""
|
|
185
|
+
|
|
186
|
+
message_id: str
|
|
187
|
+
session_key: str
|
|
188
|
+
sender_id: str
|
|
189
|
+
sender_type: str # 'master_controller', 'agent', 'user'
|
|
190
|
+
sender_role: Optional[str] # For agents
|
|
191
|
+
recipient_id: str
|
|
192
|
+
recipient_type: str # 'agent', 'master_controller', 'user'
|
|
193
|
+
recipient_role: Optional[str] # For agents
|
|
194
|
+
content: str
|
|
195
|
+
# 'task_assignment', 'result_report', 'collaboration_request', 'feedback', 'communication'
|
|
196
|
+
message_type: str
|
|
197
|
+
timestamp: datetime
|
|
198
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
199
|
+
|
|
200
|
+
def __post_init__(self):
|
|
201
|
+
"""Validate message data after initialization."""
|
|
202
|
+
if not self.message_id:
|
|
203
|
+
self.message_id = str(uuid.uuid4())
|
|
204
|
+
if not self.session_key:
|
|
205
|
+
raise ValueError("session_key cannot be empty")
|
|
206
|
+
if not self.sender_id:
|
|
207
|
+
raise ValueError("sender_id cannot be empty")
|
|
208
|
+
if not self.recipient_id:
|
|
209
|
+
raise ValueError("recipient_id cannot be empty")
|
|
210
|
+
if not self.content:
|
|
211
|
+
raise ValueError("content cannot be empty")
|
|
212
|
+
|
|
213
|
+
# Validate message types
|
|
214
|
+
valid_message_types = {
|
|
215
|
+
"task_assignment",
|
|
216
|
+
"result_report",
|
|
217
|
+
"collaboration_request",
|
|
218
|
+
"feedback",
|
|
219
|
+
"communication",
|
|
220
|
+
"status_update",
|
|
221
|
+
"error_report",
|
|
222
|
+
"task_completion",
|
|
223
|
+
"progress_update",
|
|
224
|
+
"clarification_request",
|
|
225
|
+
}
|
|
226
|
+
if self.message_type not in valid_message_types:
|
|
227
|
+
raise ValueError(f"message_type must be one of {valid_message_types}")
|
|
228
|
+
|
|
229
|
+
def to_conversation_message_dict(self) -> Dict[str, Any]:
|
|
230
|
+
"""Convert to format compatible with ContextEngine conversation messages."""
|
|
231
|
+
role = f"{self.sender_type}_{self.sender_role}" if self.sender_role else self.sender_type
|
|
232
|
+
return {
|
|
233
|
+
"role": role,
|
|
234
|
+
"content": self.content,
|
|
235
|
+
"timestamp": self.timestamp.isoformat(),
|
|
236
|
+
"metadata": {
|
|
237
|
+
**self.metadata,
|
|
238
|
+
"message_id": self.message_id,
|
|
239
|
+
"sender_id": self.sender_id,
|
|
240
|
+
"sender_type": self.sender_type,
|
|
241
|
+
"sender_role": self.sender_role,
|
|
242
|
+
"recipient_id": self.recipient_id,
|
|
243
|
+
"recipient_type": self.recipient_type,
|
|
244
|
+
"recipient_role": self.recipient_role,
|
|
245
|
+
"message_type": self.message_type,
|
|
246
|
+
},
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
250
|
+
"""Convert to dictionary for storage."""
|
|
251
|
+
return {
|
|
252
|
+
"message_id": self.message_id,
|
|
253
|
+
"session_key": self.session_key,
|
|
254
|
+
"sender_id": self.sender_id,
|
|
255
|
+
"sender_type": self.sender_type,
|
|
256
|
+
"sender_role": self.sender_role,
|
|
257
|
+
"recipient_id": self.recipient_id,
|
|
258
|
+
"recipient_type": self.recipient_type,
|
|
259
|
+
"recipient_role": self.recipient_role,
|
|
260
|
+
"content": self.content,
|
|
261
|
+
"message_type": self.message_type,
|
|
262
|
+
"timestamp": self.timestamp.isoformat(),
|
|
263
|
+
"metadata": self.metadata,
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@classmethod
|
|
267
|
+
def from_dict(cls, data: Dict[str, Any]) -> "AgentCommunicationMessage":
|
|
268
|
+
"""Create from dictionary."""
|
|
269
|
+
return cls(
|
|
270
|
+
message_id=data["message_id"],
|
|
271
|
+
session_key=data["session_key"],
|
|
272
|
+
sender_id=data["sender_id"],
|
|
273
|
+
sender_type=data["sender_type"],
|
|
274
|
+
sender_role=data.get("sender_role"),
|
|
275
|
+
recipient_id=data["recipient_id"],
|
|
276
|
+
recipient_type=data["recipient_type"],
|
|
277
|
+
recipient_role=data.get("recipient_role"),
|
|
278
|
+
content=data["content"],
|
|
279
|
+
message_type=data["message_type"],
|
|
280
|
+
timestamp=datetime.fromisoformat(data["timestamp"]),
|
|
281
|
+
metadata=data.get("metadata", {}),
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
# Conversation isolation utility functions
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def create_session_key(
|
|
289
|
+
session_id: str,
|
|
290
|
+
session_type: str,
|
|
291
|
+
participants: List[ConversationParticipant],
|
|
292
|
+
) -> str:
|
|
293
|
+
"""
|
|
294
|
+
Utility function to create session keys for conversation isolation.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
session_id: Base session ID
|
|
298
|
+
session_type: Type of conversation
|
|
299
|
+
participants: List of conversation participants
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Generated session key
|
|
303
|
+
"""
|
|
304
|
+
if session_type == "user_to_mc":
|
|
305
|
+
return session_id
|
|
306
|
+
elif session_type == "mc_to_agent":
|
|
307
|
+
agent_role = next(
|
|
308
|
+
(p.participant_role for p in participants if p.participant_type == "agent"),
|
|
309
|
+
"unknown",
|
|
310
|
+
)
|
|
311
|
+
return f"{session_id}_mc_to_{agent_role}"
|
|
312
|
+
elif session_type == "agent_to_agent":
|
|
313
|
+
agent_roles = [p.participant_role for p in participants if p.participant_type == "agent"]
|
|
314
|
+
if len(agent_roles) >= 2:
|
|
315
|
+
return f"{session_id}_{agent_roles[0]}_to_{agent_roles[1]}"
|
|
316
|
+
return f"{session_id}_agent_to_agent"
|
|
317
|
+
elif session_type == "user_to_agent":
|
|
318
|
+
agent_role = next(
|
|
319
|
+
(p.participant_role for p in participants if p.participant_type == "agent"),
|
|
320
|
+
"unknown",
|
|
321
|
+
)
|
|
322
|
+
return f"{session_id}_user_to_{agent_role}"
|
|
323
|
+
else:
|
|
324
|
+
return session_id
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def validate_conversation_isolation_pattern(session_key: str, expected_pattern: str) -> bool:
|
|
328
|
+
"""
|
|
329
|
+
Validate that a session key follows the expected conversation isolation pattern.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
session_key: The session key to validate
|
|
333
|
+
expected_pattern: Expected pattern ('user_to_mc', 'mc_to_agent', etc.)
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
True if the pattern matches, False otherwise
|
|
337
|
+
"""
|
|
338
|
+
if expected_pattern == "user_to_mc":
|
|
339
|
+
# Should be just the base session_id
|
|
340
|
+
return "_" not in session_key or not any(
|
|
341
|
+
x in session_key for x in ["_mc_to_", "_to_", "_user_to_"]
|
|
342
|
+
)
|
|
343
|
+
elif expected_pattern == "mc_to_agent":
|
|
344
|
+
return "_mc_to_" in session_key
|
|
345
|
+
elif expected_pattern == "agent_to_agent":
|
|
346
|
+
return (
|
|
347
|
+
"_to_" in session_key
|
|
348
|
+
and "_mc_to_" not in session_key
|
|
349
|
+
and "_user_to_" not in session_key
|
|
350
|
+
)
|
|
351
|
+
elif expected_pattern == "user_to_agent":
|
|
352
|
+
return "_user_to_" in session_key
|
|
353
|
+
else:
|
|
354
|
+
return False
|