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,495 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data Visualizer Tool - Smart data visualization and chart generation
|
|
3
|
+
|
|
4
|
+
This tool provides intelligent visualization capabilities with:
|
|
5
|
+
- Auto chart type recommendation
|
|
6
|
+
- Multiple chart types support
|
|
7
|
+
- Interactive and static visualizations
|
|
8
|
+
- Export in multiple formats
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import logging
|
|
13
|
+
import tempfile
|
|
14
|
+
from typing import Dict, Any, List, Optional, Union
|
|
15
|
+
from enum import Enum
|
|
16
|
+
|
|
17
|
+
import pandas as pd
|
|
18
|
+
import numpy as np
|
|
19
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
20
|
+
|
|
21
|
+
from aiecs.tools.base_tool import BaseTool
|
|
22
|
+
from aiecs.tools import register_tool
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ChartType(str, Enum):
|
|
26
|
+
"""Supported chart types"""
|
|
27
|
+
|
|
28
|
+
# Basic charts
|
|
29
|
+
LINE = "line"
|
|
30
|
+
BAR = "bar"
|
|
31
|
+
SCATTER = "scatter"
|
|
32
|
+
HISTOGRAM = "histogram"
|
|
33
|
+
BOX = "box"
|
|
34
|
+
VIOLIN = "violin"
|
|
35
|
+
|
|
36
|
+
# Advanced charts
|
|
37
|
+
HEATMAP = "heatmap"
|
|
38
|
+
CORRELATION_MATRIX = "correlation_matrix"
|
|
39
|
+
PAIR_PLOT = "pair_plot"
|
|
40
|
+
PARALLEL_COORDINATES = "parallel_coordinates"
|
|
41
|
+
|
|
42
|
+
# Statistical charts
|
|
43
|
+
DISTRIBUTION = "distribution"
|
|
44
|
+
QQ_PLOT = "qq_plot"
|
|
45
|
+
RESIDUAL_PLOT = "residual_plot"
|
|
46
|
+
|
|
47
|
+
# Time series
|
|
48
|
+
TIME_SERIES = "time_series"
|
|
49
|
+
|
|
50
|
+
# Auto-detect
|
|
51
|
+
AUTO = "auto"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class VisualizationStyle(str, Enum):
|
|
55
|
+
"""Visualization styles"""
|
|
56
|
+
|
|
57
|
+
STATIC = "static"
|
|
58
|
+
INTERACTIVE = "interactive"
|
|
59
|
+
ANIMATED = "animated"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class DataVisualizerError(Exception):
|
|
63
|
+
"""Base exception for DataVisualizer errors"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class VisualizationError(DataVisualizerError):
|
|
67
|
+
"""Raised when visualization fails"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@register_tool("data_visualizer")
|
|
71
|
+
class DataVisualizerTool(BaseTool):
|
|
72
|
+
"""
|
|
73
|
+
Intelligent data visualization tool that can:
|
|
74
|
+
1. Auto-recommend appropriate chart types
|
|
75
|
+
2. Generate interactive visualizations
|
|
76
|
+
3. Create multi-dimensional plots
|
|
77
|
+
4. Export in multiple formats
|
|
78
|
+
|
|
79
|
+
Integrates with chart_tool for core visualization operations.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
# Configuration schema
|
|
83
|
+
class Config(BaseModel):
|
|
84
|
+
"""Configuration for the data visualizer tool"""
|
|
85
|
+
|
|
86
|
+
model_config = ConfigDict(env_prefix="DATA_VISUALIZER_")
|
|
87
|
+
|
|
88
|
+
default_style: str = Field(default="static", description="Default visualization style")
|
|
89
|
+
default_output_dir: str = Field(
|
|
90
|
+
default=tempfile.gettempdir(),
|
|
91
|
+
description="Default directory for output files",
|
|
92
|
+
)
|
|
93
|
+
default_dpi: int = Field(default=100, description="Default DPI for image exports")
|
|
94
|
+
default_figsize: List[int] = Field(
|
|
95
|
+
default=[10, 6],
|
|
96
|
+
description="Default figure size in inches (width, height)",
|
|
97
|
+
)
|
|
98
|
+
enable_auto_recommendation: bool = Field(
|
|
99
|
+
default=True,
|
|
100
|
+
description="Whether to enable automatic chart type recommendation",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
104
|
+
"""
|
|
105
|
+
Initialize DataVisualizerTool with settings.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
config: Optional configuration overrides
|
|
109
|
+
"""
|
|
110
|
+
super().__init__(config)
|
|
111
|
+
|
|
112
|
+
# Parse configuration
|
|
113
|
+
self.config = self.Config(**(config or {}))
|
|
114
|
+
|
|
115
|
+
self.logger = logging.getLogger(__name__)
|
|
116
|
+
if not self.logger.handlers:
|
|
117
|
+
handler = logging.StreamHandler()
|
|
118
|
+
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
|
|
119
|
+
self.logger.addHandler(handler)
|
|
120
|
+
self.logger.setLevel(logging.INFO)
|
|
121
|
+
|
|
122
|
+
# Initialize external tools
|
|
123
|
+
self._init_external_tools()
|
|
124
|
+
|
|
125
|
+
def _init_external_tools(self):
|
|
126
|
+
"""Initialize external task tools"""
|
|
127
|
+
self.external_tools = {}
|
|
128
|
+
|
|
129
|
+
# Initialize ChartTool for visualization operations
|
|
130
|
+
try:
|
|
131
|
+
from aiecs.tools.task_tools.chart_tool import ChartTool
|
|
132
|
+
|
|
133
|
+
self.external_tools["chart"] = ChartTool()
|
|
134
|
+
self.logger.info("ChartTool initialized successfully")
|
|
135
|
+
except ImportError:
|
|
136
|
+
self.logger.warning("ChartTool not available")
|
|
137
|
+
self.external_tools["chart"] = None
|
|
138
|
+
|
|
139
|
+
# Schema definitions
|
|
140
|
+
class VisualizeSchema(BaseModel):
|
|
141
|
+
"""Schema for visualize operation"""
|
|
142
|
+
|
|
143
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]]] = Field(description="Data to visualize")
|
|
144
|
+
chart_type: ChartType = Field(default=ChartType.AUTO, description="Type of chart")
|
|
145
|
+
x: Optional[str] = Field(default=None, description="X-axis column")
|
|
146
|
+
y: Optional[str] = Field(default=None, description="Y-axis column")
|
|
147
|
+
hue: Optional[str] = Field(default=None, description="Hue/color column")
|
|
148
|
+
style: VisualizationStyle = Field(
|
|
149
|
+
default=VisualizationStyle.STATIC,
|
|
150
|
+
description="Visualization style",
|
|
151
|
+
)
|
|
152
|
+
title: Optional[str] = Field(default=None, description="Chart title")
|
|
153
|
+
output_path: Optional[str] = Field(default=None, description="Output file path")
|
|
154
|
+
|
|
155
|
+
class AutoVisualizeDatasetSchema(BaseModel):
|
|
156
|
+
"""Schema for auto_visualize_dataset operation"""
|
|
157
|
+
|
|
158
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]]] = Field(
|
|
159
|
+
description="Dataset to visualize"
|
|
160
|
+
)
|
|
161
|
+
max_charts: int = Field(default=10, description="Maximum number of charts to generate")
|
|
162
|
+
focus_areas: Optional[List[str]] = Field(default=None, description="Areas to focus on")
|
|
163
|
+
|
|
164
|
+
class RecommendChartTypeSchema(BaseModel):
|
|
165
|
+
"""Schema for recommend_chart_type operation"""
|
|
166
|
+
|
|
167
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]]] = Field(
|
|
168
|
+
description="Data for recommendation"
|
|
169
|
+
)
|
|
170
|
+
x: Optional[str] = Field(default=None, description="X column")
|
|
171
|
+
y: Optional[str] = Field(default=None, description="Y column")
|
|
172
|
+
|
|
173
|
+
def visualize(
|
|
174
|
+
self,
|
|
175
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
|
|
176
|
+
chart_type: ChartType = ChartType.AUTO,
|
|
177
|
+
x: Optional[str] = None,
|
|
178
|
+
y: Optional[str] = None,
|
|
179
|
+
hue: Optional[str] = None,
|
|
180
|
+
style: VisualizationStyle = VisualizationStyle.STATIC,
|
|
181
|
+
title: Optional[str] = None,
|
|
182
|
+
output_path: Optional[str] = None,
|
|
183
|
+
) -> Dict[str, Any]:
|
|
184
|
+
"""
|
|
185
|
+
Create visualization with auto chart type recommendation.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
data: Data to visualize
|
|
189
|
+
chart_type: Type of chart (auto-recommended if AUTO)
|
|
190
|
+
x: X-axis column name
|
|
191
|
+
y: Y-axis column name
|
|
192
|
+
hue: Column for color encoding
|
|
193
|
+
style: Visualization style
|
|
194
|
+
title: Chart title
|
|
195
|
+
output_path: Path to save the chart
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Dict containing:
|
|
199
|
+
- chart_info: Information about generated chart
|
|
200
|
+
- chart_type: Type of chart created
|
|
201
|
+
- recommendation_reason: Reason for chart type choice
|
|
202
|
+
- output_path: Path to saved chart (if saved)
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
VisualizationError: If visualization fails
|
|
206
|
+
"""
|
|
207
|
+
try:
|
|
208
|
+
df = self._to_dataframe(data)
|
|
209
|
+
|
|
210
|
+
# Auto-recommend chart type if needed
|
|
211
|
+
if chart_type == ChartType.AUTO:
|
|
212
|
+
chart_type, reason = self._recommend_chart_type(df, x, y)
|
|
213
|
+
self.logger.info(f"Auto-recommended chart type: {chart_type.value} - {reason}")
|
|
214
|
+
else:
|
|
215
|
+
reason = "User specified"
|
|
216
|
+
|
|
217
|
+
# Generate output path if not provided
|
|
218
|
+
if output_path is None:
|
|
219
|
+
output_path = os.path.join(
|
|
220
|
+
self.config.default_output_dir,
|
|
221
|
+
f"chart_{chart_type.value}_{pd.Timestamp.now().strftime('%Y%m%d_%H%M%S')}.png",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Create visualization using chart_tool if available
|
|
225
|
+
if self.external_tools.get("chart"):
|
|
226
|
+
chart_result = self._create_chart_with_tool(
|
|
227
|
+
df, chart_type, x, y, hue, title, output_path
|
|
228
|
+
)
|
|
229
|
+
else:
|
|
230
|
+
chart_result = self._create_chart_matplotlib(
|
|
231
|
+
df, chart_type, x, y, hue, title, output_path
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
"chart_info": chart_result,
|
|
236
|
+
"chart_type": chart_type.value,
|
|
237
|
+
"recommendation_reason": reason,
|
|
238
|
+
"output_path": output_path,
|
|
239
|
+
"style": style.value,
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
except Exception as e:
|
|
243
|
+
self.logger.error(f"Error creating visualization: {e}")
|
|
244
|
+
raise VisualizationError(f"Visualization failed: {e}")
|
|
245
|
+
|
|
246
|
+
def auto_visualize_dataset(
|
|
247
|
+
self,
|
|
248
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
|
|
249
|
+
max_charts: int = 10,
|
|
250
|
+
focus_areas: Optional[List[str]] = None,
|
|
251
|
+
) -> Dict[str, Any]:
|
|
252
|
+
"""
|
|
253
|
+
Automatically generate a comprehensive visualization suite.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
data: Dataset to visualize
|
|
257
|
+
max_charts: Maximum number of charts to generate
|
|
258
|
+
focus_areas: Specific areas to focus on (distributions, correlations, outliers)
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Dict containing information about all generated charts
|
|
262
|
+
"""
|
|
263
|
+
try:
|
|
264
|
+
df = self._to_dataframe(data)
|
|
265
|
+
|
|
266
|
+
generated_charts = []
|
|
267
|
+
chart_count = 0
|
|
268
|
+
|
|
269
|
+
# Default focus areas
|
|
270
|
+
if focus_areas is None:
|
|
271
|
+
focus_areas = ["distributions", "correlations", "outliers"]
|
|
272
|
+
|
|
273
|
+
# Generate distribution charts
|
|
274
|
+
if "distributions" in focus_areas and chart_count < max_charts:
|
|
275
|
+
numeric_cols = df.select_dtypes(include=[np.number]).columns[:5]
|
|
276
|
+
for col in numeric_cols:
|
|
277
|
+
if chart_count >= max_charts:
|
|
278
|
+
break
|
|
279
|
+
chart_info = self.visualize(
|
|
280
|
+
df,
|
|
281
|
+
ChartType.HISTOGRAM,
|
|
282
|
+
x=col,
|
|
283
|
+
title=f"Distribution of {col}",
|
|
284
|
+
)
|
|
285
|
+
generated_charts.append(chart_info)
|
|
286
|
+
chart_count += 1
|
|
287
|
+
|
|
288
|
+
# Generate correlation matrix
|
|
289
|
+
if "correlations" in focus_areas and chart_count < max_charts:
|
|
290
|
+
numeric_cols = df.select_dtypes(include=[np.number]).columns
|
|
291
|
+
if len(numeric_cols) >= 2:
|
|
292
|
+
chart_info = self.visualize(
|
|
293
|
+
df,
|
|
294
|
+
ChartType.CORRELATION_MATRIX,
|
|
295
|
+
title="Correlation Matrix",
|
|
296
|
+
)
|
|
297
|
+
generated_charts.append(chart_info)
|
|
298
|
+
chart_count += 1
|
|
299
|
+
|
|
300
|
+
# Generate box plots for outlier detection
|
|
301
|
+
if "outliers" in focus_areas and chart_count < max_charts:
|
|
302
|
+
numeric_cols = df.select_dtypes(include=[np.number]).columns[:3]
|
|
303
|
+
for col in numeric_cols:
|
|
304
|
+
if chart_count >= max_charts:
|
|
305
|
+
break
|
|
306
|
+
chart_info = self.visualize(
|
|
307
|
+
df, ChartType.BOX, y=col, title=f"Box Plot of {col}"
|
|
308
|
+
)
|
|
309
|
+
generated_charts.append(chart_info)
|
|
310
|
+
chart_count += 1
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
"generated_charts": generated_charts,
|
|
314
|
+
"total_charts": len(generated_charts),
|
|
315
|
+
"focus_areas": focus_areas,
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
except Exception as e:
|
|
319
|
+
self.logger.error(f"Error in auto visualization: {e}")
|
|
320
|
+
raise VisualizationError(f"Auto visualization failed: {e}")
|
|
321
|
+
|
|
322
|
+
def recommend_chart_type(
|
|
323
|
+
self,
|
|
324
|
+
data: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
|
|
325
|
+
x: Optional[str] = None,
|
|
326
|
+
y: Optional[str] = None,
|
|
327
|
+
) -> Dict[str, Any]:
|
|
328
|
+
"""
|
|
329
|
+
Recommend appropriate chart type based on data characteristics.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
data: Data for analysis
|
|
333
|
+
x: X column name
|
|
334
|
+
y: Y column name
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Dict containing recommended chart type and reasoning
|
|
338
|
+
"""
|
|
339
|
+
try:
|
|
340
|
+
df = self._to_dataframe(data)
|
|
341
|
+
chart_type, reason = self._recommend_chart_type(df, x, y)
|
|
342
|
+
|
|
343
|
+
return {
|
|
344
|
+
"recommended_chart": chart_type.value,
|
|
345
|
+
"reason": reason,
|
|
346
|
+
"confidence": "high",
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
except Exception as e:
|
|
350
|
+
self.logger.error(f"Error recommending chart type: {e}")
|
|
351
|
+
raise VisualizationError(f"Chart recommendation failed: {e}")
|
|
352
|
+
|
|
353
|
+
# Internal helper methods
|
|
354
|
+
|
|
355
|
+
def _to_dataframe(self, data: Union[Dict, List, pd.DataFrame]) -> pd.DataFrame:
|
|
356
|
+
"""Convert data to DataFrame"""
|
|
357
|
+
if isinstance(data, pd.DataFrame):
|
|
358
|
+
return data
|
|
359
|
+
elif isinstance(data, list):
|
|
360
|
+
return pd.DataFrame(data)
|
|
361
|
+
elif isinstance(data, dict):
|
|
362
|
+
return pd.DataFrame([data])
|
|
363
|
+
else:
|
|
364
|
+
raise VisualizationError(f"Unsupported data type: {type(data)}")
|
|
365
|
+
|
|
366
|
+
def _recommend_chart_type(self, df: pd.DataFrame, x: Optional[str], y: Optional[str]) -> tuple:
|
|
367
|
+
"""Recommend chart type based on data characteristics"""
|
|
368
|
+
# If no columns specified, recommend based on data structure
|
|
369
|
+
if x is None and y is None:
|
|
370
|
+
numeric_cols = df.select_dtypes(include=[np.number]).columns
|
|
371
|
+
if len(numeric_cols) >= 2:
|
|
372
|
+
return (
|
|
373
|
+
ChartType.CORRELATION_MATRIX,
|
|
374
|
+
"Multiple numeric columns detected",
|
|
375
|
+
)
|
|
376
|
+
elif len(numeric_cols) == 1:
|
|
377
|
+
return ChartType.HISTOGRAM, "Single numeric column detected"
|
|
378
|
+
else:
|
|
379
|
+
return ChartType.BAR, "Categorical data detected"
|
|
380
|
+
|
|
381
|
+
# Determine column types
|
|
382
|
+
x_is_numeric = x and df[x].dtype in ["int64", "float64"] if x in df.columns else False
|
|
383
|
+
y_is_numeric = y and df[y].dtype in ["int64", "float64"] if y in df.columns else False
|
|
384
|
+
|
|
385
|
+
# Both numeric: scatter or line
|
|
386
|
+
if x_is_numeric and y_is_numeric:
|
|
387
|
+
# Check if x looks like time series
|
|
388
|
+
if x and "date" in x.lower() or "time" in x.lower():
|
|
389
|
+
return ChartType.TIME_SERIES, "Time series data detected"
|
|
390
|
+
return ChartType.SCATTER, "Two numeric variables"
|
|
391
|
+
|
|
392
|
+
# One numeric, one categorical: bar or box
|
|
393
|
+
if (x_is_numeric and not y_is_numeric) or (not x_is_numeric and y_is_numeric):
|
|
394
|
+
return ChartType.BAR, "Mix of numeric and categorical"
|
|
395
|
+
|
|
396
|
+
# Both categorical: bar
|
|
397
|
+
if x and y and not x_is_numeric and not y_is_numeric:
|
|
398
|
+
return ChartType.BAR, "Two categorical variables"
|
|
399
|
+
|
|
400
|
+
# Single numeric: histogram
|
|
401
|
+
if (x_is_numeric and y is None) or (y_is_numeric and x is None):
|
|
402
|
+
return ChartType.HISTOGRAM, "Single numeric variable distribution"
|
|
403
|
+
|
|
404
|
+
# Default
|
|
405
|
+
return ChartType.BAR, "Default chart type"
|
|
406
|
+
|
|
407
|
+
def _create_chart_with_tool(
|
|
408
|
+
self,
|
|
409
|
+
df: pd.DataFrame,
|
|
410
|
+
chart_type: ChartType,
|
|
411
|
+
x: Optional[str],
|
|
412
|
+
y: Optional[str],
|
|
413
|
+
hue: Optional[str],
|
|
414
|
+
title: Optional[str],
|
|
415
|
+
output_path: str,
|
|
416
|
+
) -> Dict[str, Any]:
|
|
417
|
+
"""Create chart using chart_tool"""
|
|
418
|
+
chart_tool = self.external_tools["chart"]
|
|
419
|
+
|
|
420
|
+
# Convert chart type to chart_tool format
|
|
421
|
+
chart_config = {
|
|
422
|
+
"data": df.to_dict("records"),
|
|
423
|
+
"chart_type": chart_type.value,
|
|
424
|
+
"x": x,
|
|
425
|
+
"y": y,
|
|
426
|
+
"title": title or f"{chart_type.value.title()} Chart",
|
|
427
|
+
"output_path": output_path,
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
try:
|
|
431
|
+
result = chart_tool.run("create_chart", **chart_config)
|
|
432
|
+
return result
|
|
433
|
+
except Exception as e:
|
|
434
|
+
self.logger.warning(f"chart_tool failed, falling back to matplotlib: {e}")
|
|
435
|
+
return self._create_chart_matplotlib(df, chart_type, x, y, hue, title, output_path)
|
|
436
|
+
|
|
437
|
+
def _create_chart_matplotlib(
|
|
438
|
+
self,
|
|
439
|
+
df: pd.DataFrame,
|
|
440
|
+
chart_type: ChartType,
|
|
441
|
+
x: Optional[str],
|
|
442
|
+
y: Optional[str],
|
|
443
|
+
hue: Optional[str],
|
|
444
|
+
title: Optional[str],
|
|
445
|
+
output_path: str,
|
|
446
|
+
) -> Dict[str, Any]:
|
|
447
|
+
"""Create chart using matplotlib as fallback"""
|
|
448
|
+
import matplotlib.pyplot as plt
|
|
449
|
+
|
|
450
|
+
fig, ax = plt.subplots(figsize=self.config.default_figsize)
|
|
451
|
+
|
|
452
|
+
if chart_type == ChartType.HISTOGRAM and x:
|
|
453
|
+
ax.hist(df[x].dropna(), bins=30, edgecolor="black")
|
|
454
|
+
ax.set_xlabel(x)
|
|
455
|
+
ax.set_ylabel("Frequency")
|
|
456
|
+
elif chart_type == ChartType.SCATTER and x and y:
|
|
457
|
+
ax.scatter(df[x], df[y], alpha=0.6)
|
|
458
|
+
ax.set_xlabel(x)
|
|
459
|
+
ax.set_ylabel(y)
|
|
460
|
+
elif chart_type == ChartType.BAR and x and y:
|
|
461
|
+
df_grouped = df.groupby(x)[y].mean()
|
|
462
|
+
df_grouped.plot(kind="bar", ax=ax)
|
|
463
|
+
ax.set_xlabel(x)
|
|
464
|
+
ax.set_ylabel(y)
|
|
465
|
+
elif chart_type == ChartType.CORRELATION_MATRIX:
|
|
466
|
+
numeric_df = df.select_dtypes(include=[np.number])
|
|
467
|
+
if len(numeric_df.columns) >= 2:
|
|
468
|
+
corr = numeric_df.corr()
|
|
469
|
+
im = ax.imshow(corr, cmap="coolwarm", aspect="auto")
|
|
470
|
+
ax.set_xticks(range(len(corr.columns)))
|
|
471
|
+
ax.set_yticks(range(len(corr.columns)))
|
|
472
|
+
ax.set_xticklabels(corr.columns, rotation=45, ha="right")
|
|
473
|
+
ax.set_yticklabels(corr.columns)
|
|
474
|
+
plt.colorbar(im, ax=ax)
|
|
475
|
+
elif chart_type == ChartType.BOX and y:
|
|
476
|
+
df.boxplot(column=y, ax=ax)
|
|
477
|
+
else:
|
|
478
|
+
# Default: simple line plot
|
|
479
|
+
if x and y:
|
|
480
|
+
ax.plot(df[x], df[y])
|
|
481
|
+
elif x:
|
|
482
|
+
ax.plot(df[x])
|
|
483
|
+
|
|
484
|
+
if title:
|
|
485
|
+
ax.set_title(title)
|
|
486
|
+
|
|
487
|
+
plt.tight_layout()
|
|
488
|
+
plt.savefig(output_path, dpi=self.config.default_dpi, bbox_inches="tight")
|
|
489
|
+
plt.close()
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
"status": "success",
|
|
493
|
+
"output_path": output_path,
|
|
494
|
+
"chart_type": chart_type.value,
|
|
495
|
+
}
|