aiecs 1.0.1__py3-none-any.whl → 1.7.17__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 +435 -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 +3949 -0
- aiecs/domain/agent/exceptions.py +99 -0
- aiecs/domain/agent/graph_aware_mixin.py +569 -0
- aiecs/domain/agent/hybrid_agent.py +1731 -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 +894 -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 +377 -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 +230 -37
- aiecs/llm/client_resolver.py +155 -0
- aiecs/llm/clients/__init__.py +38 -0
- aiecs/llm/clients/base_client.py +328 -0
- aiecs/llm/clients/google_function_calling_mixin.py +415 -0
- aiecs/llm/clients/googleai_client.py +314 -0
- aiecs/llm/clients/openai_client.py +158 -0
- aiecs/llm/clients/openai_compatible_mixin.py +367 -0
- aiecs/llm/clients/vertex_client.py +1186 -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 +1464 -0
- aiecs/tools/docs/document_layout_tool.py +1160 -0
- aiecs/tools/docs/document_parser_tool.py +1016 -0
- aiecs/tools/docs/document_writer_tool.py +2008 -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 +220 -141
- 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.17.dist-info}/METADATA +52 -15
- aiecs-1.7.17.dist-info/RECORD +337 -0
- aiecs-1.7.17.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.17.dist-info}/WHEEL +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/licenses/LICENSE +0 -0
- {aiecs-1.0.1.dist-info → aiecs-1.7.17.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration validation utilities for LLM models.
|
|
3
|
+
|
|
4
|
+
This module provides validation functions to ensure configuration integrity
|
|
5
|
+
and provide helpful error messages.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import List, Tuple
|
|
10
|
+
|
|
11
|
+
from aiecs.llm.config.model_config import (
|
|
12
|
+
LLMModelsConfig,
|
|
13
|
+
ProviderConfig,
|
|
14
|
+
ModelConfig,
|
|
15
|
+
ModelCostConfig,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ConfigValidationError(Exception):
|
|
22
|
+
"""Raised when configuration validation fails"""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def validate_cost_config(cost_config: ModelCostConfig, model_name: str) -> List[str]:
|
|
26
|
+
"""
|
|
27
|
+
Validate cost configuration.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
cost_config: Cost configuration to validate
|
|
31
|
+
model_name: Name of the model (for error messages)
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of warning messages (empty if valid)
|
|
35
|
+
"""
|
|
36
|
+
warnings = []
|
|
37
|
+
|
|
38
|
+
if cost_config.input < 0:
|
|
39
|
+
raise ConfigValidationError(f"Model '{model_name}': Input cost must be non-negative, got {cost_config.input}")
|
|
40
|
+
|
|
41
|
+
if cost_config.output < 0:
|
|
42
|
+
raise ConfigValidationError(f"Model '{model_name}': Output cost must be non-negative, got {cost_config.output}")
|
|
43
|
+
|
|
44
|
+
# Warn if costs are zero (might be intentional for free tiers or unknown
|
|
45
|
+
# pricing)
|
|
46
|
+
if cost_config.input == 0 and cost_config.output == 0:
|
|
47
|
+
warnings.append(f"Model '{model_name}': Both input and output costs are 0")
|
|
48
|
+
|
|
49
|
+
return warnings
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def validate_model_config(model_config: ModelConfig) -> List[str]:
|
|
53
|
+
"""
|
|
54
|
+
Validate a single model configuration.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
model_config: Model configuration to validate
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
List of warning messages (empty if valid)
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
ConfigValidationError: If validation fails
|
|
64
|
+
"""
|
|
65
|
+
warnings = []
|
|
66
|
+
|
|
67
|
+
# Validate name
|
|
68
|
+
if not model_config.name or not model_config.name.strip():
|
|
69
|
+
raise ConfigValidationError("Model name cannot be empty")
|
|
70
|
+
|
|
71
|
+
# Validate costs
|
|
72
|
+
cost_warnings = validate_cost_config(model_config.costs, model_config.name)
|
|
73
|
+
warnings.extend(cost_warnings)
|
|
74
|
+
|
|
75
|
+
# Validate capabilities
|
|
76
|
+
if model_config.capabilities.max_tokens <= 0:
|
|
77
|
+
raise ConfigValidationError(f"Model '{model_config.name}': max_tokens must be positive, " f"got {model_config.capabilities.max_tokens}")
|
|
78
|
+
|
|
79
|
+
if model_config.capabilities.context_window <= 0:
|
|
80
|
+
raise ConfigValidationError(f"Model '{model_config.name}': context_window must be positive, " f"got {model_config.capabilities.context_window}")
|
|
81
|
+
|
|
82
|
+
# Validate default params
|
|
83
|
+
if not (0.0 <= model_config.default_params.temperature <= 2.0):
|
|
84
|
+
raise ConfigValidationError(f"Model '{model_config.name}': temperature must be between 0.0 and 2.0, " f"got {model_config.default_params.temperature}")
|
|
85
|
+
|
|
86
|
+
if model_config.default_params.max_tokens <= 0:
|
|
87
|
+
raise ConfigValidationError(f"Model '{model_config.name}': default max_tokens must be positive, " f"got {model_config.default_params.max_tokens}")
|
|
88
|
+
|
|
89
|
+
# Warn if default max_tokens exceeds capability max_tokens
|
|
90
|
+
if model_config.default_params.max_tokens > model_config.capabilities.max_tokens:
|
|
91
|
+
warnings.append(f"Model '{model_config.name}': default max_tokens ({model_config.default_params.max_tokens}) " f"exceeds capability max_tokens ({model_config.capabilities.max_tokens})")
|
|
92
|
+
|
|
93
|
+
return warnings
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def validate_provider_config(provider_config: ProviderConfig) -> List[str]:
|
|
97
|
+
"""
|
|
98
|
+
Validate a provider configuration.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
provider_config: Provider configuration to validate
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
List of warning messages (empty if valid)
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
ConfigValidationError: If validation fails
|
|
108
|
+
"""
|
|
109
|
+
warnings = []
|
|
110
|
+
|
|
111
|
+
# Validate provider name
|
|
112
|
+
if not provider_config.provider_name or not provider_config.provider_name.strip():
|
|
113
|
+
raise ConfigValidationError("Provider name cannot be empty")
|
|
114
|
+
|
|
115
|
+
# Validate models list
|
|
116
|
+
if not provider_config.models:
|
|
117
|
+
raise ConfigValidationError(f"Provider '{provider_config.provider_name}': Must have at least one model")
|
|
118
|
+
|
|
119
|
+
# Validate default model exists
|
|
120
|
+
model_names = provider_config.get_model_names()
|
|
121
|
+
if provider_config.default_model not in model_names:
|
|
122
|
+
raise ConfigValidationError(f"Provider '{provider_config.provider_name}': Default model '{provider_config.default_model}' " f"not found in models list: {model_names}")
|
|
123
|
+
|
|
124
|
+
# Validate each model
|
|
125
|
+
for model in provider_config.models:
|
|
126
|
+
model_warnings = validate_model_config(model)
|
|
127
|
+
warnings.extend(model_warnings)
|
|
128
|
+
|
|
129
|
+
# Check for duplicate model names
|
|
130
|
+
if len(model_names) != len(set(model_names)):
|
|
131
|
+
duplicates = [name for name in model_names if model_names.count(name) > 1]
|
|
132
|
+
raise ConfigValidationError(f"Provider '{provider_config.provider_name}': Duplicate model names found: {set(duplicates)}")
|
|
133
|
+
|
|
134
|
+
# Validate model mappings if present
|
|
135
|
+
if provider_config.model_mappings:
|
|
136
|
+
for alias, target in provider_config.model_mappings.items():
|
|
137
|
+
if target not in model_names:
|
|
138
|
+
raise ConfigValidationError(f"Provider '{provider_config.provider_name}': Model mapping alias '{alias}' " f"points to non-existent model '{target}'. Available models: {model_names}")
|
|
139
|
+
|
|
140
|
+
# Warn if alias is the same as target
|
|
141
|
+
if alias == target:
|
|
142
|
+
warnings.append(f"Provider '{provider_config.provider_name}': Model mapping has redundant entry " f"'{alias}' -> '{target}'")
|
|
143
|
+
|
|
144
|
+
return warnings
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def validate_llm_config(config: LLMModelsConfig) -> Tuple[bool, List[str]]:
|
|
148
|
+
"""
|
|
149
|
+
Validate the entire LLM configuration.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
config: Complete LLM configuration to validate
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Tuple of (is_valid, warnings_list)
|
|
156
|
+
|
|
157
|
+
Raises:
|
|
158
|
+
ConfigValidationError: If validation fails critically
|
|
159
|
+
"""
|
|
160
|
+
warnings = []
|
|
161
|
+
|
|
162
|
+
# Validate providers exist
|
|
163
|
+
if not config.providers:
|
|
164
|
+
raise ConfigValidationError("Configuration must have at least one provider")
|
|
165
|
+
|
|
166
|
+
# Validate each provider
|
|
167
|
+
for provider_name, provider_config in config.providers.items():
|
|
168
|
+
try:
|
|
169
|
+
provider_warnings = validate_provider_config(provider_config)
|
|
170
|
+
warnings.extend(provider_warnings)
|
|
171
|
+
except ConfigValidationError as e:
|
|
172
|
+
raise ConfigValidationError(f"Provider '{provider_name}': {e}")
|
|
173
|
+
|
|
174
|
+
# Log warnings
|
|
175
|
+
if warnings:
|
|
176
|
+
logger.warning(f"Configuration validation completed with {len(warnings)} warnings:")
|
|
177
|
+
for warning in warnings:
|
|
178
|
+
logger.warning(f" - {warning}")
|
|
179
|
+
else:
|
|
180
|
+
logger.info("Configuration validation completed successfully with no warnings")
|
|
181
|
+
|
|
182
|
+
return True, warnings
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def validate_config_file(config_path: str) -> Tuple[bool, List[str]]:
|
|
186
|
+
"""
|
|
187
|
+
Validate a configuration file.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
config_path: Path to the configuration file
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Tuple of (is_valid, warnings_list)
|
|
194
|
+
|
|
195
|
+
Raises:
|
|
196
|
+
ConfigValidationError: If validation fails
|
|
197
|
+
FileNotFoundError: If file doesn't exist
|
|
198
|
+
"""
|
|
199
|
+
from aiecs.llm.config.config_loader import LLMConfigLoader
|
|
200
|
+
from pathlib import Path
|
|
201
|
+
|
|
202
|
+
loader = LLMConfigLoader()
|
|
203
|
+
config_path_obj: Path | None = Path(config_path) if config_path else None
|
|
204
|
+
config = loader.load_config(config_path_obj)
|
|
205
|
+
|
|
206
|
+
return validate_llm_config(config)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pydantic models for LLM configuration management.
|
|
3
|
+
|
|
4
|
+
This module defines the configuration schema for all LLM providers and models,
|
|
5
|
+
enabling centralized, type-safe configuration management.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Optional, List
|
|
9
|
+
from pydantic import BaseModel, Field, field_validator
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ModelCostConfig(BaseModel):
|
|
13
|
+
"""Token cost configuration for a model"""
|
|
14
|
+
|
|
15
|
+
input: float = Field(ge=0, description="Cost per 1K input tokens in USD")
|
|
16
|
+
output: float = Field(ge=0, description="Cost per 1K output tokens in USD")
|
|
17
|
+
|
|
18
|
+
@field_validator("input", "output")
|
|
19
|
+
@classmethod
|
|
20
|
+
def validate_positive(cls, v: float) -> float:
|
|
21
|
+
"""Ensure costs are non-negative"""
|
|
22
|
+
if v < 0:
|
|
23
|
+
raise ValueError("Cost must be non-negative")
|
|
24
|
+
return v
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ModelCapabilities(BaseModel):
|
|
28
|
+
"""Capabilities and limits for a model"""
|
|
29
|
+
|
|
30
|
+
streaming: bool = Field(default=True, description="Whether the model supports streaming")
|
|
31
|
+
vision: bool = Field(
|
|
32
|
+
default=False,
|
|
33
|
+
description="Whether the model supports vision/image input",
|
|
34
|
+
)
|
|
35
|
+
function_calling: bool = Field(
|
|
36
|
+
default=False,
|
|
37
|
+
description="Whether the model supports function calling",
|
|
38
|
+
)
|
|
39
|
+
max_tokens: int = Field(default=8192, ge=1, description="Maximum output tokens")
|
|
40
|
+
context_window: int = Field(default=128000, ge=1, description="Maximum context window size")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ModelDefaultParams(BaseModel):
|
|
44
|
+
"""Default parameters for model inference"""
|
|
45
|
+
|
|
46
|
+
temperature: float = Field(default=0.7, ge=0.0, le=2.0, description="Default temperature")
|
|
47
|
+
max_tokens: int = Field(default=8192, ge=1, description="Default max output tokens")
|
|
48
|
+
top_p: float = Field(default=0.95, ge=0.0, le=1.0, description="Default top_p")
|
|
49
|
+
top_k: int = Field(default=40, ge=0, description="Default top_k")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ModelConfig(BaseModel):
|
|
53
|
+
"""Complete configuration for a single model"""
|
|
54
|
+
|
|
55
|
+
name: str = Field(description="Model identifier")
|
|
56
|
+
display_name: Optional[str] = Field(default=None, description="Human-readable model name")
|
|
57
|
+
costs: ModelCostConfig = Field(description="Token cost configuration")
|
|
58
|
+
capabilities: ModelCapabilities = Field(default_factory=ModelCapabilities, description="Model capabilities")
|
|
59
|
+
default_params: ModelDefaultParams = Field(default_factory=ModelDefaultParams, description="Default parameters")
|
|
60
|
+
description: Optional[str] = Field(default=None, description="Model description")
|
|
61
|
+
|
|
62
|
+
def __init__(self, **data):
|
|
63
|
+
super().__init__(**data)
|
|
64
|
+
# Set display_name to name if not provided
|
|
65
|
+
if self.display_name is None:
|
|
66
|
+
self.display_name = self.name
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ProviderConfig(BaseModel):
|
|
70
|
+
"""Configuration for a single LLM provider"""
|
|
71
|
+
|
|
72
|
+
provider_name: str = Field(description="Provider identifier")
|
|
73
|
+
default_model: str = Field(description="Default model for this provider")
|
|
74
|
+
models: List[ModelConfig] = Field(description="List of available models")
|
|
75
|
+
model_mappings: Optional[Dict[str, str]] = Field(
|
|
76
|
+
default=None,
|
|
77
|
+
description="Model name aliases (e.g., 'Grok 4' -> 'grok-4')",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
@field_validator("models")
|
|
81
|
+
@classmethod
|
|
82
|
+
def validate_models_not_empty(cls, v: List[ModelConfig]) -> List[ModelConfig]:
|
|
83
|
+
"""Ensure at least one model is configured"""
|
|
84
|
+
if not v:
|
|
85
|
+
raise ValueError("Provider must have at least one model configured")
|
|
86
|
+
return v
|
|
87
|
+
|
|
88
|
+
def get_model_config(self, model_name: str) -> Optional[ModelConfig]:
|
|
89
|
+
"""Get configuration for a specific model"""
|
|
90
|
+
# First, check if this is an alias
|
|
91
|
+
if self.model_mappings and model_name in self.model_mappings:
|
|
92
|
+
model_name = self.model_mappings[model_name]
|
|
93
|
+
|
|
94
|
+
# Find the model configuration
|
|
95
|
+
for model in self.models:
|
|
96
|
+
if model.name == model_name:
|
|
97
|
+
return model
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
def get_model_names(self) -> List[str]:
|
|
101
|
+
"""Get list of all model names"""
|
|
102
|
+
return [model.name for model in self.models]
|
|
103
|
+
|
|
104
|
+
def get_all_model_names_with_aliases(self) -> List[str]:
|
|
105
|
+
"""Get list of all model names including aliases"""
|
|
106
|
+
names = self.get_model_names()
|
|
107
|
+
if self.model_mappings:
|
|
108
|
+
names.extend(list(self.model_mappings.keys()))
|
|
109
|
+
return names
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class LLMModelsConfig(BaseModel):
|
|
113
|
+
"""Root configuration containing all providers"""
|
|
114
|
+
|
|
115
|
+
providers: Dict[str, ProviderConfig] = Field(description="Provider configurations keyed by provider name")
|
|
116
|
+
|
|
117
|
+
@field_validator("providers")
|
|
118
|
+
@classmethod
|
|
119
|
+
def validate_providers_not_empty(cls, v: Dict[str, ProviderConfig]) -> Dict[str, ProviderConfig]:
|
|
120
|
+
"""Ensure at least one provider is configured"""
|
|
121
|
+
if not v:
|
|
122
|
+
raise ValueError("At least one provider must be configured")
|
|
123
|
+
return v
|
|
124
|
+
|
|
125
|
+
def get_provider_config(self, provider_name: str) -> Optional[ProviderConfig]:
|
|
126
|
+
"""Get configuration for a specific provider"""
|
|
127
|
+
# Normalize provider name (case-insensitive lookup)
|
|
128
|
+
provider_name_lower = provider_name.lower()
|
|
129
|
+
for key, config in self.providers.items():
|
|
130
|
+
if key.lower() == provider_name_lower:
|
|
131
|
+
return config
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
def get_model_config(self, provider_name: str, model_name: str) -> Optional[ModelConfig]:
|
|
135
|
+
"""Get configuration for a specific model from a provider"""
|
|
136
|
+
provider_config = self.get_provider_config(provider_name)
|
|
137
|
+
if provider_config:
|
|
138
|
+
return provider_config.get_model_config(model_name)
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
def get_provider_names(self) -> List[str]:
|
|
142
|
+
"""Get list of all provider names"""
|
|
143
|
+
return list(self.providers.keys())
|
aiecs/llm/protocols.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLM Client Protocols
|
|
3
|
+
|
|
4
|
+
Defines Protocol interfaces for LLM clients to enable duck typing and flexible integration.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Protocol, List, Optional, AsyncGenerator, runtime_checkable
|
|
8
|
+
from aiecs.llm.clients.base_client import LLMMessage, LLMResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@runtime_checkable
|
|
12
|
+
class LLMClientProtocol(Protocol):
|
|
13
|
+
"""
|
|
14
|
+
Protocol for LLM clients.
|
|
15
|
+
|
|
16
|
+
This protocol defines the interface that any LLM client must implement
|
|
17
|
+
to be compatible with AIECS agents. It uses duck typing (Protocol) rather
|
|
18
|
+
than inheritance, allowing custom LLM clients to work without inheriting
|
|
19
|
+
from BaseLLMClient.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
```python
|
|
23
|
+
# Custom LLM client that implements the protocol
|
|
24
|
+
class CustomLLMClient:
|
|
25
|
+
def __init__(self):
|
|
26
|
+
self.provider_name = "custom"
|
|
27
|
+
|
|
28
|
+
async def generate_text(
|
|
29
|
+
self,
|
|
30
|
+
messages: List[LLMMessage],
|
|
31
|
+
model: Optional[str] = None,
|
|
32
|
+
temperature: float = 0.7,
|
|
33
|
+
max_tokens: Optional[int] = None,
|
|
34
|
+
**kwargs
|
|
35
|
+
) -> LLMResponse:
|
|
36
|
+
# Custom implementation
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
async def stream_text(
|
|
40
|
+
self,
|
|
41
|
+
messages: List[LLMMessage],
|
|
42
|
+
model: Optional[str] = None,
|
|
43
|
+
temperature: float = 0.7,
|
|
44
|
+
max_tokens: Optional[int] = None,
|
|
45
|
+
**kwargs
|
|
46
|
+
) -> AsyncGenerator[str, None]:
|
|
47
|
+
# Custom implementation
|
|
48
|
+
yield "token"
|
|
49
|
+
|
|
50
|
+
async def close(self):
|
|
51
|
+
# Cleanup
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
# Use with agents
|
|
55
|
+
agent = HybridAgent(
|
|
56
|
+
llm_client=CustomLLMClient(), # Works without BaseLLMClient inheritance!
|
|
57
|
+
...
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
provider_name: str
|
|
63
|
+
|
|
64
|
+
async def generate_text(
|
|
65
|
+
self,
|
|
66
|
+
messages: List[LLMMessage],
|
|
67
|
+
model: Optional[str] = None,
|
|
68
|
+
temperature: float = 0.7,
|
|
69
|
+
max_tokens: Optional[int] = None,
|
|
70
|
+
**kwargs,
|
|
71
|
+
) -> LLMResponse:
|
|
72
|
+
"""
|
|
73
|
+
Generate text using the LLM provider's API.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
messages: List of conversation messages
|
|
77
|
+
model: Model name (optional, uses default if not provided)
|
|
78
|
+
temperature: Sampling temperature (0.0 to 1.0)
|
|
79
|
+
max_tokens: Maximum tokens to generate
|
|
80
|
+
**kwargs: Additional provider-specific parameters
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
LLMResponse with generated text and metadata
|
|
84
|
+
"""
|
|
85
|
+
...
|
|
86
|
+
|
|
87
|
+
async def stream_text(
|
|
88
|
+
self,
|
|
89
|
+
messages: List[LLMMessage],
|
|
90
|
+
model: Optional[str] = None,
|
|
91
|
+
temperature: float = 0.7,
|
|
92
|
+
max_tokens: Optional[int] = None,
|
|
93
|
+
**kwargs,
|
|
94
|
+
) -> AsyncGenerator[str, None]:
|
|
95
|
+
"""
|
|
96
|
+
Stream text generation using the LLM provider's API.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
messages: List of conversation messages
|
|
100
|
+
model: Model name (optional, uses default if not provided)
|
|
101
|
+
temperature: Sampling temperature (0.0 to 1.0)
|
|
102
|
+
max_tokens: Maximum tokens to generate
|
|
103
|
+
**kwargs: Additional provider-specific parameters
|
|
104
|
+
|
|
105
|
+
Yields:
|
|
106
|
+
Text tokens as they are generated
|
|
107
|
+
"""
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
async def close(self):
|
|
111
|
+
"""
|
|
112
|
+
Clean up resources (connections, sessions, etc.).
|
|
113
|
+
|
|
114
|
+
This method should be called when the client is no longer needed.
|
|
115
|
+
"""
|
|
116
|
+
...
|
|
117
|
+
|
|
118
|
+
async def get_embeddings(
|
|
119
|
+
self,
|
|
120
|
+
texts: List[str],
|
|
121
|
+
model: Optional[str] = None,
|
|
122
|
+
**kwargs,
|
|
123
|
+
) -> List[List[float]]:
|
|
124
|
+
"""
|
|
125
|
+
Get embeddings for a list of texts.
|
|
126
|
+
|
|
127
|
+
This method is used for semantic compression and similarity analysis.
|
|
128
|
+
Implementations should return normalized embeddings for cosine similarity.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
texts: List of texts to embed
|
|
132
|
+
model: Embedding model name (optional, uses default if not provided)
|
|
133
|
+
**kwargs: Additional provider-specific parameters
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
List of embedding vectors (one per input text)
|
|
137
|
+
|
|
138
|
+
Example:
|
|
139
|
+
```python
|
|
140
|
+
texts = ["Hello world", "Goodbye world"]
|
|
141
|
+
embeddings = await llm_client.get_embeddings(texts)
|
|
142
|
+
# embeddings = [[0.1, 0.2, ...], [0.15, 0.25, ...]]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Note:
|
|
146
|
+
Not all LLM clients support embeddings. If not supported,
|
|
147
|
+
this method should raise NotImplementedError.
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Validation script for LLM models configuration.
|
|
4
|
+
|
|
5
|
+
This script validates the LLM models configuration file and prints
|
|
6
|
+
information about configured providers and models.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import logging
|
|
11
|
+
|
|
12
|
+
# Setup logging
|
|
13
|
+
logging.basicConfig(
|
|
14
|
+
level=logging.INFO,
|
|
15
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
16
|
+
)
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
"""Main validation function"""
|
|
22
|
+
try:
|
|
23
|
+
from aiecs.llm.config import get_llm_config_loader, validate_llm_config
|
|
24
|
+
|
|
25
|
+
logger.info("=" * 70)
|
|
26
|
+
logger.info("LLM Models Configuration Validator")
|
|
27
|
+
logger.info("=" * 70)
|
|
28
|
+
|
|
29
|
+
# Load configuration
|
|
30
|
+
loader = get_llm_config_loader()
|
|
31
|
+
config = loader.get_config()
|
|
32
|
+
|
|
33
|
+
logger.info(f"\nConfiguration loaded from: {loader.get_config_path()}")
|
|
34
|
+
|
|
35
|
+
# Validate configuration
|
|
36
|
+
logger.info("\nValidating configuration...")
|
|
37
|
+
is_valid, warnings = validate_llm_config(config)
|
|
38
|
+
|
|
39
|
+
if is_valid:
|
|
40
|
+
logger.info("✓ Configuration is valid!")
|
|
41
|
+
|
|
42
|
+
# Print summary
|
|
43
|
+
logger.info("\n" + "=" * 70)
|
|
44
|
+
logger.info("Configuration Summary")
|
|
45
|
+
logger.info("=" * 70)
|
|
46
|
+
|
|
47
|
+
logger.info(f"\nTotal Providers: {len(config.providers)}")
|
|
48
|
+
|
|
49
|
+
for provider_name, provider_config in config.providers.items():
|
|
50
|
+
logger.info(f"\n{provider_name}:")
|
|
51
|
+
logger.info(f" Default Model: {provider_config.default_model}")
|
|
52
|
+
logger.info(f" Total Models: {len(provider_config.models)}")
|
|
53
|
+
|
|
54
|
+
if provider_config.model_mappings:
|
|
55
|
+
logger.info(f" Model Aliases: {len(provider_config.model_mappings)}")
|
|
56
|
+
|
|
57
|
+
logger.info(" Available Models:")
|
|
58
|
+
for model in provider_config.models:
|
|
59
|
+
cost_str = f"${model.costs.input:.6f} in / ${model.costs.output:.6f} out (per 1K tokens)"
|
|
60
|
+
logger.info(f" - {model.name}: {cost_str}")
|
|
61
|
+
if model.capabilities.vision:
|
|
62
|
+
logger.info(" Vision: Yes")
|
|
63
|
+
if model.capabilities.function_calling:
|
|
64
|
+
logger.info(" Function Calling: Yes")
|
|
65
|
+
|
|
66
|
+
logger.info("\n" + "=" * 70)
|
|
67
|
+
logger.info("Validation Complete!")
|
|
68
|
+
logger.info("=" * 70)
|
|
69
|
+
|
|
70
|
+
if warnings:
|
|
71
|
+
logger.info(f"\nNote: {len(warnings)} warnings were generated during validation.")
|
|
72
|
+
logger.info("See logs above for details.")
|
|
73
|
+
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
except FileNotFoundError as e:
|
|
77
|
+
logger.error(f"\n✗ Configuration file not found: {e}")
|
|
78
|
+
logger.error("\nPlease ensure the LLM models configuration file exists at:")
|
|
79
|
+
logger.error(" - aiecs/config/llm_models.yaml")
|
|
80
|
+
logger.error(" - Or set LLM_MODELS_CONFIG environment variable")
|
|
81
|
+
return 1
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
logger.error(f"\n✗ Validation failed: {e}", exc_info=True)
|
|
85
|
+
return 1
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
sys.exit(main())
|