abstractcore 2.4.8__tar.gz → 2.5.0__tar.gz
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.
- {abstractcore-2.4.8 → abstractcore-2.5.0}/PKG-INFO +5 -1
- {abstractcore-2.4.8 → abstractcore-2.5.0}/README.md +4 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/app_config_utils.py +1 -1
- abstractcore-2.5.0/abstractcore/config/__init__.py +10 -0
- {abstractcore-2.4.8/abstractcore/cli → abstractcore-2.5.0/abstractcore/config}/main.py +24 -5
- abstractcore-2.5.0/abstractcore/config/manager.py +344 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/vision_fallback.py +16 -2
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/version.py +1 -1
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/PKG-INFO +5 -1
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/SOURCES.txt +4 -3
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/entry_points.txt +2 -2
- {abstractcore-2.4.8 → abstractcore-2.5.0}/pyproject.toml +3 -3
- abstractcore-2.4.8/abstractcore/cli/__init__.py +0 -9
- {abstractcore-2.4.8 → abstractcore-2.5.0}/LICENSE +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/__main__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/extractor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/judge.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/apps/summarizer.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/architectures/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/architectures/detection.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/architectures/enums.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/assets/architecture_formats.json +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/assets/model_capabilities.json +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/assets/session_schema.json +0 -0
- {abstractcore-2.4.8/abstractcore/cli → abstractcore-2.5.0/abstractcore/config}/vision_config.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/enums.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/factory.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/interface.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/retry.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/session.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/core/types.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/embeddings/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/embeddings/manager.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/embeddings/models.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/events/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/exceptions/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/auto_handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/base.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/capabilities.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/handlers/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/handlers/anthropic_handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/handlers/local_handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/handlers/openai_handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/processors/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/processors/image_processor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/processors/office_processor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/processors/pdf_processor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/processors/text_processor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/types.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/utils/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/media/utils/image_scaler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/processing/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/processing/basic_extractor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/processing/basic_judge.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/processing/basic_summarizer.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/anthropic_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/base.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/huggingface_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/lmstudio_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/mlx_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/ollama_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/openai_provider.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/registry.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/providers/streaming.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/server/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/server/app.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/structured/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/structured/handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/structured/retry.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/common_tools.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/core.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/handler.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/parser.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/registry.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/syntax_rewriter.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/tools/tag_rewriter.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/__init__.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/cli.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/message_preprocessor.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/self_fixes.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/structured_logging.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore/utils/token_utils.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/dependency_links.txt +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/requires.txt +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/abstractcore.egg-info/top_level.txt +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/setup.cfg +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_agentic_cli_compatibility.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_all_specified_providers.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_basic_session.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_basic_summarizer.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_cli_media.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_complete_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_comprehensive_events.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_consistency.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_core_components.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_critical_streaming_tool_fix.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_debug_server.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_direct_vs_server.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_llm_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_matrix_operations.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_no_mock.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_real.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_semantic_validation.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_embeddings_simple.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_enhanced_prompt.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_environment_variable_tool_call_tags.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_factory.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_final_accuracy.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_final_comprehensive.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_final_graceful_errors.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_fixed_media.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_fixed_prompt.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_graceful_fallback.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_import_debug.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_integrated_functionality.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_lmstudio_context.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_media_import.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_media_server.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_ollama_tool_role_fix.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_openai_conversion_manual.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_openai_format_bug.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_openai_format_conversion.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_openai_media_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_progressive_complexity.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_basic_session.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_connectivity.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_simple_generation.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_streaming.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_token_translation.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_provider_tool_detection.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_providers.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_providers_comprehensive.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_providers_simple.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_real_models_comprehensive.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_retry_observability.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_retry_strategy.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_seed_determinism.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_seed_temperature_basic.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_sensory_prompting.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_server_debug.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_server_embeddings_real.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_server_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_stream_tool_calling.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_streaming_enhancements.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_streaming_tag_rewriting.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_structured_integration.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_structured_output.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_syntax_rewriter.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_text_only_model_experience.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_tool_calling.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_tool_execution_separation.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_unified_streaming.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_unload_memory.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_user_scenario_validation.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_vision_accuracy.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_vision_comprehensive.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_vision_fallback_improvement.py +0 -0
- {abstractcore-2.4.8 → abstractcore-2.5.0}/tests/test_wrong_model_fallback.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractcore
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Unified interface to all LLM providers with essential infrastructure for tool calling, streaming, and model management
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
6
|
Maintainer-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
@@ -551,6 +551,10 @@ abstractcore --set-console-log-level NONE # Disable console logging
|
|
|
551
551
|
abstractcore --enable-file-logging # Save logs to files
|
|
552
552
|
abstractcore --enable-debug-logging # Full debug mode
|
|
553
553
|
|
|
554
|
+
# Configure vision for image analysis with text-only models
|
|
555
|
+
abstractcore --set-vision-provider ollama qwen2.5vl:7b
|
|
556
|
+
abstractcore --set-vision-provider lmstudio qwen/qwen3-vl-4b
|
|
557
|
+
|
|
554
558
|
# Set API keys as needed
|
|
555
559
|
abstractcore --set-api-key openai sk-your-key-here
|
|
556
560
|
abstractcore --set-api-key anthropic your-anthropic-key
|
|
@@ -451,6 +451,10 @@ abstractcore --set-console-log-level NONE # Disable console logging
|
|
|
451
451
|
abstractcore --enable-file-logging # Save logs to files
|
|
452
452
|
abstractcore --enable-debug-logging # Full debug mode
|
|
453
453
|
|
|
454
|
+
# Configure vision for image analysis with text-only models
|
|
455
|
+
abstractcore --set-vision-provider ollama qwen2.5vl:7b
|
|
456
|
+
abstractcore --set-vision-provider lmstudio qwen/qwen3-vl-4b
|
|
457
|
+
|
|
454
458
|
# Set API keys as needed
|
|
455
459
|
abstractcore --set-api-key openai sk-your-key-here
|
|
456
460
|
abstractcore --set-api-key anthropic your-anthropic-key
|
|
@@ -8,7 +8,7 @@ def get_app_defaults(app_name: str) -> tuple[str, str]:
|
|
|
8
8
|
from ..config import get_config_manager
|
|
9
9
|
config_manager = get_config_manager()
|
|
10
10
|
return config_manager.get_app_default(app_name)
|
|
11
|
-
except Exception:
|
|
11
|
+
except (ImportError, Exception):
|
|
12
12
|
# Fallback to hardcoded defaults if config unavailable
|
|
13
13
|
hardcoded_defaults = {
|
|
14
14
|
'summarizer': ('huggingface', 'unsloth/Qwen3-4B-Instruct-2507-GGUF'),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AbstractCore Configuration Module
|
|
3
|
+
|
|
4
|
+
Provides configuration management and command-line interface for AbstractCore.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .vision_config import handle_vision_commands, add_vision_arguments
|
|
8
|
+
from .manager import get_config_manager
|
|
9
|
+
|
|
10
|
+
__all__ = ['handle_vision_commands', 'add_vision_arguments', 'get_config_manager']
|
|
@@ -38,7 +38,13 @@ from typing import List, Optional
|
|
|
38
38
|
# Add parent directory to path for imports
|
|
39
39
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
# Import config manager with fallback
|
|
42
|
+
try:
|
|
43
|
+
from abstractcore.config import get_config_manager
|
|
44
|
+
CONFIG_AVAILABLE = True
|
|
45
|
+
except ImportError:
|
|
46
|
+
CONFIG_AVAILABLE = False
|
|
47
|
+
get_config_manager = None
|
|
42
48
|
|
|
43
49
|
def download_vision_model(model_name: str = "blip-base-caption") -> bool:
|
|
44
50
|
"""Download a vision model for local use."""
|
|
@@ -144,10 +150,12 @@ def download_vision_model(model_name: str = "blip-base-caption") -> bool:
|
|
|
144
150
|
print(f"📁 Model saved to: {models_dir}")
|
|
145
151
|
|
|
146
152
|
# Configure AbstractCore to use this model
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
if CONFIG_AVAILABLE:
|
|
154
|
+
config_manager = get_config_manager()
|
|
155
|
+
# Use the proper HuggingFace model identifier
|
|
156
|
+
config_manager.set_vision_provider("huggingface", hf_id)
|
|
157
|
+
else:
|
|
158
|
+
print("⚠️ Config system not available - manual configuration required")
|
|
151
159
|
|
|
152
160
|
print(f"✅ Configured AbstractCore to use HuggingFace model: {hf_id}")
|
|
153
161
|
print(f"🎯 Vision fallback is now enabled!")
|
|
@@ -256,6 +264,11 @@ def add_arguments(parser: argparse.ArgumentParser):
|
|
|
256
264
|
|
|
257
265
|
def print_status():
|
|
258
266
|
"""Print comprehensive configuration status with improved readability."""
|
|
267
|
+
if not CONFIG_AVAILABLE or get_config_manager is None:
|
|
268
|
+
print("❌ Configuration system not available")
|
|
269
|
+
print("💡 The AbstractCore configuration module is missing")
|
|
270
|
+
return
|
|
271
|
+
|
|
259
272
|
config_manager = get_config_manager()
|
|
260
273
|
status = config_manager.get_status()
|
|
261
274
|
|
|
@@ -486,6 +499,12 @@ def interactive_configure():
|
|
|
486
499
|
|
|
487
500
|
def handle_commands(args) -> bool:
|
|
488
501
|
"""Handle AbstractCore configuration commands."""
|
|
502
|
+
if not CONFIG_AVAILABLE or get_config_manager is None:
|
|
503
|
+
print("❌ Error: Configuration system not available")
|
|
504
|
+
print("💡 The AbstractCore configuration module is missing or not properly installed")
|
|
505
|
+
print("💡 Please reinstall AbstractCore or check your installation")
|
|
506
|
+
return True
|
|
507
|
+
|
|
489
508
|
config_manager = get_config_manager()
|
|
490
509
|
handled = False
|
|
491
510
|
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AbstractCore Configuration Manager
|
|
3
|
+
|
|
4
|
+
Provides centralized configuration management for AbstractCore.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, Any, Optional, Tuple
|
|
11
|
+
from dataclasses import dataclass, asdict
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class VisionConfig:
|
|
16
|
+
"""Vision configuration settings."""
|
|
17
|
+
strategy: str = "disabled"
|
|
18
|
+
caption_provider: Optional[str] = None
|
|
19
|
+
caption_model: Optional[str] = None
|
|
20
|
+
fallback_chain: list = None
|
|
21
|
+
local_models_path: Optional[str] = None
|
|
22
|
+
|
|
23
|
+
def __post_init__(self):
|
|
24
|
+
if self.fallback_chain is None:
|
|
25
|
+
self.fallback_chain = []
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class EmbeddingsConfig:
|
|
30
|
+
"""Embeddings configuration settings."""
|
|
31
|
+
provider: Optional[str] = "huggingface"
|
|
32
|
+
model: Optional[str] = "all-minilm-l6-v2"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class AppDefaults:
|
|
37
|
+
"""Per-application default configurations."""
|
|
38
|
+
cli_provider: Optional[str] = "huggingface"
|
|
39
|
+
cli_model: Optional[str] = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
|
|
40
|
+
summarizer_provider: Optional[str] = "huggingface"
|
|
41
|
+
summarizer_model: Optional[str] = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
|
|
42
|
+
extractor_provider: Optional[str] = "huggingface"
|
|
43
|
+
extractor_model: Optional[str] = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
|
|
44
|
+
judge_provider: Optional[str] = "huggingface"
|
|
45
|
+
judge_model: Optional[str] = "unsloth/Qwen3-4B-Instruct-2507-GGUF"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class DefaultModels:
|
|
50
|
+
"""Global default model configurations."""
|
|
51
|
+
global_provider: Optional[str] = None
|
|
52
|
+
global_model: Optional[str] = None
|
|
53
|
+
chat_model: Optional[str] = None
|
|
54
|
+
code_model: Optional[str] = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class ApiKeysConfig:
|
|
59
|
+
"""API keys configuration."""
|
|
60
|
+
openai: Optional[str] = None
|
|
61
|
+
anthropic: Optional[str] = None
|
|
62
|
+
google: Optional[str] = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class CacheConfig:
|
|
67
|
+
"""Cache configuration settings."""
|
|
68
|
+
default_cache_dir: str = "~/.cache/abstractcore"
|
|
69
|
+
huggingface_cache_dir: str = "~/.cache/huggingface"
|
|
70
|
+
local_models_cache_dir: str = "~/.abstractcore/models"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass
|
|
74
|
+
class LoggingConfig:
|
|
75
|
+
"""Logging configuration settings."""
|
|
76
|
+
console_level: str = "WARNING"
|
|
77
|
+
file_level: str = "DEBUG"
|
|
78
|
+
file_logging_enabled: bool = False
|
|
79
|
+
log_base_dir: Optional[str] = None
|
|
80
|
+
verbatim_enabled: bool = True
|
|
81
|
+
console_json: bool = False
|
|
82
|
+
file_json: bool = True
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class AbstractCoreConfig:
|
|
87
|
+
"""Main configuration class."""
|
|
88
|
+
vision: VisionConfig
|
|
89
|
+
embeddings: EmbeddingsConfig
|
|
90
|
+
app_defaults: AppDefaults
|
|
91
|
+
default_models: DefaultModels
|
|
92
|
+
api_keys: ApiKeysConfig
|
|
93
|
+
cache: CacheConfig
|
|
94
|
+
logging: LoggingConfig
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def default(cls):
|
|
98
|
+
"""Create default configuration."""
|
|
99
|
+
return cls(
|
|
100
|
+
vision=VisionConfig(),
|
|
101
|
+
embeddings=EmbeddingsConfig(),
|
|
102
|
+
app_defaults=AppDefaults(),
|
|
103
|
+
default_models=DefaultModels(),
|
|
104
|
+
api_keys=ApiKeysConfig(),
|
|
105
|
+
cache=CacheConfig(),
|
|
106
|
+
logging=LoggingConfig()
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ConfigurationManager:
|
|
111
|
+
"""Manages AbstractCore configuration."""
|
|
112
|
+
|
|
113
|
+
def __init__(self):
|
|
114
|
+
self.config_dir = Path.home() / ".abstractcore" / "config"
|
|
115
|
+
self.config_file = self.config_dir / "abstractcore.json"
|
|
116
|
+
self.config = self._load_config()
|
|
117
|
+
|
|
118
|
+
def _load_config(self) -> AbstractCoreConfig:
|
|
119
|
+
"""Load configuration from file or create default."""
|
|
120
|
+
if self.config_file.exists():
|
|
121
|
+
try:
|
|
122
|
+
with open(self.config_file, 'r') as f:
|
|
123
|
+
data = json.load(f)
|
|
124
|
+
return self._dict_to_config(data)
|
|
125
|
+
except Exception:
|
|
126
|
+
# If loading fails, return default config
|
|
127
|
+
return AbstractCoreConfig.default()
|
|
128
|
+
else:
|
|
129
|
+
return AbstractCoreConfig.default()
|
|
130
|
+
|
|
131
|
+
def _dict_to_config(self, data: Dict[str, Any]) -> AbstractCoreConfig:
|
|
132
|
+
"""Convert dictionary to config object."""
|
|
133
|
+
# Create config objects from dictionary data
|
|
134
|
+
vision = VisionConfig(**data.get('vision', {}))
|
|
135
|
+
embeddings = EmbeddingsConfig(**data.get('embeddings', {}))
|
|
136
|
+
app_defaults = AppDefaults(**data.get('app_defaults', {}))
|
|
137
|
+
default_models = DefaultModels(**data.get('default_models', {}))
|
|
138
|
+
api_keys = ApiKeysConfig(**data.get('api_keys', {}))
|
|
139
|
+
cache = CacheConfig(**data.get('cache', {}))
|
|
140
|
+
logging = LoggingConfig(**data.get('logging', {}))
|
|
141
|
+
|
|
142
|
+
return AbstractCoreConfig(
|
|
143
|
+
vision=vision,
|
|
144
|
+
embeddings=embeddings,
|
|
145
|
+
app_defaults=app_defaults,
|
|
146
|
+
default_models=default_models,
|
|
147
|
+
api_keys=api_keys,
|
|
148
|
+
cache=cache,
|
|
149
|
+
logging=logging
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def _save_config(self):
|
|
153
|
+
"""Save configuration to file."""
|
|
154
|
+
self.config_dir.mkdir(parents=True, exist_ok=True)
|
|
155
|
+
|
|
156
|
+
# Convert config to dictionary
|
|
157
|
+
config_dict = {
|
|
158
|
+
'vision': asdict(self.config.vision),
|
|
159
|
+
'embeddings': asdict(self.config.embeddings),
|
|
160
|
+
'app_defaults': asdict(self.config.app_defaults),
|
|
161
|
+
'default_models': asdict(self.config.default_models),
|
|
162
|
+
'api_keys': asdict(self.config.api_keys),
|
|
163
|
+
'cache': asdict(self.config.cache),
|
|
164
|
+
'logging': asdict(self.config.logging)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
with open(self.config_file, 'w') as f:
|
|
168
|
+
json.dump(config_dict, f, indent=2)
|
|
169
|
+
|
|
170
|
+
def set_vision_provider(self, provider: str, model: str) -> bool:
|
|
171
|
+
"""Set vision provider and model."""
|
|
172
|
+
try:
|
|
173
|
+
self.config.vision.strategy = "two_stage"
|
|
174
|
+
self.config.vision.caption_provider = provider
|
|
175
|
+
self.config.vision.caption_model = model
|
|
176
|
+
self._save_config()
|
|
177
|
+
return True
|
|
178
|
+
except Exception:
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
def set_vision_caption(self, model: str) -> bool:
|
|
182
|
+
"""Set vision caption model (deprecated)."""
|
|
183
|
+
# Auto-detect provider from model name
|
|
184
|
+
provider = self._detect_provider_from_model(model)
|
|
185
|
+
if provider:
|
|
186
|
+
return self.set_vision_provider(provider, model)
|
|
187
|
+
return False
|
|
188
|
+
|
|
189
|
+
def _detect_provider_from_model(self, model: str) -> Optional[str]:
|
|
190
|
+
"""Detect provider from model name."""
|
|
191
|
+
model_lower = model.lower()
|
|
192
|
+
|
|
193
|
+
if any(x in model_lower for x in ['qwen2.5vl', 'llama3.2-vision', 'llava']):
|
|
194
|
+
return "ollama"
|
|
195
|
+
elif any(x in model_lower for x in ['gpt-4', 'gpt-4o']):
|
|
196
|
+
return "openai"
|
|
197
|
+
elif any(x in model_lower for x in ['claude-3']):
|
|
198
|
+
return "anthropic"
|
|
199
|
+
elif '/' in model:
|
|
200
|
+
return "lmstudio"
|
|
201
|
+
|
|
202
|
+
return None
|
|
203
|
+
|
|
204
|
+
def get_status(self) -> Dict[str, Any]:
|
|
205
|
+
"""Get configuration status."""
|
|
206
|
+
return {
|
|
207
|
+
"config_file": str(self.config_file),
|
|
208
|
+
"vision": {
|
|
209
|
+
"strategy": self.config.vision.strategy,
|
|
210
|
+
"status": "✅ Ready" if self.config.vision.caption_provider else "❌ Not configured",
|
|
211
|
+
"caption_provider": self.config.vision.caption_provider,
|
|
212
|
+
"caption_model": self.config.vision.caption_model
|
|
213
|
+
},
|
|
214
|
+
"app_defaults": {
|
|
215
|
+
"cli": {
|
|
216
|
+
"provider": self.config.app_defaults.cli_provider,
|
|
217
|
+
"model": self.config.app_defaults.cli_model
|
|
218
|
+
},
|
|
219
|
+
"summarizer": {
|
|
220
|
+
"provider": self.config.app_defaults.summarizer_provider,
|
|
221
|
+
"model": self.config.app_defaults.summarizer_model
|
|
222
|
+
},
|
|
223
|
+
"extractor": {
|
|
224
|
+
"provider": self.config.app_defaults.extractor_provider,
|
|
225
|
+
"model": self.config.app_defaults.extractor_model
|
|
226
|
+
},
|
|
227
|
+
"judge": {
|
|
228
|
+
"provider": self.config.app_defaults.judge_provider,
|
|
229
|
+
"model": self.config.app_defaults.judge_model
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
"global_defaults": {
|
|
233
|
+
"provider": self.config.default_models.global_provider,
|
|
234
|
+
"model": self.config.default_models.global_model,
|
|
235
|
+
"chat_model": self.config.default_models.chat_model,
|
|
236
|
+
"code_model": self.config.default_models.code_model
|
|
237
|
+
},
|
|
238
|
+
"embeddings": {
|
|
239
|
+
"status": "✅ Ready",
|
|
240
|
+
"provider": self.config.embeddings.provider,
|
|
241
|
+
"model": self.config.embeddings.model
|
|
242
|
+
},
|
|
243
|
+
"streaming": {
|
|
244
|
+
"cli_stream_default": False # Default value
|
|
245
|
+
},
|
|
246
|
+
"logging": {
|
|
247
|
+
"console_level": self.config.logging.console_level,
|
|
248
|
+
"file_level": self.config.logging.file_level,
|
|
249
|
+
"file_logging_enabled": self.config.logging.file_logging_enabled
|
|
250
|
+
},
|
|
251
|
+
"cache": {
|
|
252
|
+
"default_cache_dir": self.config.cache.default_cache_dir
|
|
253
|
+
},
|
|
254
|
+
"api_keys": {
|
|
255
|
+
"openai": "✅ Set" if self.config.api_keys.openai else "❌ Not set",
|
|
256
|
+
"anthropic": "✅ Set" if self.config.api_keys.anthropic else "❌ Not set",
|
|
257
|
+
"google": "✅ Set" if self.config.api_keys.google else "❌ Not set"
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
def set_global_default_model(self, provider_model: str) -> bool:
|
|
262
|
+
"""Set global default model in provider/model format."""
|
|
263
|
+
try:
|
|
264
|
+
if '/' in provider_model:
|
|
265
|
+
provider, model = provider_model.split('/', 1)
|
|
266
|
+
else:
|
|
267
|
+
# Assume it's just a model name, use default provider
|
|
268
|
+
provider = "ollama"
|
|
269
|
+
model = provider_model
|
|
270
|
+
|
|
271
|
+
self.config.default_models.global_provider = provider
|
|
272
|
+
self.config.default_models.global_model = model
|
|
273
|
+
self._save_config()
|
|
274
|
+
return True
|
|
275
|
+
except Exception:
|
|
276
|
+
return False
|
|
277
|
+
|
|
278
|
+
def set_app_default(self, app_name: str, provider: str, model: str) -> bool:
|
|
279
|
+
"""Set app-specific default provider and model."""
|
|
280
|
+
try:
|
|
281
|
+
if app_name == "cli":
|
|
282
|
+
self.config.app_defaults.cli_provider = provider
|
|
283
|
+
self.config.app_defaults.cli_model = model
|
|
284
|
+
elif app_name == "summarizer":
|
|
285
|
+
self.config.app_defaults.summarizer_provider = provider
|
|
286
|
+
self.config.app_defaults.summarizer_model = model
|
|
287
|
+
elif app_name == "extractor":
|
|
288
|
+
self.config.app_defaults.extractor_provider = provider
|
|
289
|
+
self.config.app_defaults.extractor_model = model
|
|
290
|
+
elif app_name == "judge":
|
|
291
|
+
self.config.app_defaults.judge_provider = provider
|
|
292
|
+
self.config.app_defaults.judge_model = model
|
|
293
|
+
else:
|
|
294
|
+
raise ValueError(f"Unknown app: {app_name}")
|
|
295
|
+
|
|
296
|
+
self._save_config()
|
|
297
|
+
return True
|
|
298
|
+
except Exception:
|
|
299
|
+
return False
|
|
300
|
+
|
|
301
|
+
def set_api_key(self, provider: str, key: str) -> bool:
|
|
302
|
+
"""Set API key for a provider."""
|
|
303
|
+
try:
|
|
304
|
+
if provider == "openai":
|
|
305
|
+
self.config.api_keys.openai = key
|
|
306
|
+
elif provider == "anthropic":
|
|
307
|
+
self.config.api_keys.anthropic = key
|
|
308
|
+
elif provider == "google":
|
|
309
|
+
self.config.api_keys.google = key
|
|
310
|
+
else:
|
|
311
|
+
return False
|
|
312
|
+
|
|
313
|
+
self._save_config()
|
|
314
|
+
return True
|
|
315
|
+
except Exception:
|
|
316
|
+
return False
|
|
317
|
+
|
|
318
|
+
def get_app_default(self, app_name: str) -> Tuple[str, str]:
|
|
319
|
+
"""Get default provider and model for an app."""
|
|
320
|
+
app_defaults = self.config.app_defaults
|
|
321
|
+
|
|
322
|
+
if app_name == "cli":
|
|
323
|
+
return app_defaults.cli_provider, app_defaults.cli_model
|
|
324
|
+
elif app_name == "summarizer":
|
|
325
|
+
return app_defaults.summarizer_provider, app_defaults.summarizer_model
|
|
326
|
+
elif app_name == "extractor":
|
|
327
|
+
return app_defaults.extractor_provider, app_defaults.extractor_model
|
|
328
|
+
elif app_name == "judge":
|
|
329
|
+
return app_defaults.judge_provider, app_defaults.judge_model
|
|
330
|
+
else:
|
|
331
|
+
# Return default fallback
|
|
332
|
+
return "huggingface", "unsloth/Qwen3-4B-Instruct-2507-GGUF"
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
# Global instance
|
|
336
|
+
_config_manager = None
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def get_config_manager() -> ConfigurationManager:
|
|
340
|
+
"""Get the global configuration manager instance."""
|
|
341
|
+
global _config_manager
|
|
342
|
+
if _config_manager is None:
|
|
343
|
+
_config_manager = ConfigurationManager()
|
|
344
|
+
return _config_manager
|
|
@@ -31,14 +31,28 @@ class VisionFallbackHandler:
|
|
|
31
31
|
def __init__(self, config_manager=None):
|
|
32
32
|
"""Initialize with configuration manager."""
|
|
33
33
|
if config_manager is None:
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
try:
|
|
35
|
+
from abstractcore.config import get_config_manager
|
|
36
|
+
self.config_manager = get_config_manager()
|
|
37
|
+
except ImportError:
|
|
38
|
+
# Config module not available - use fallback behavior
|
|
39
|
+
logger.warning("Config module not available, vision fallback disabled")
|
|
40
|
+
self.config_manager = None
|
|
36
41
|
else:
|
|
37
42
|
self.config_manager = config_manager
|
|
38
43
|
|
|
39
44
|
@property
|
|
40
45
|
def vision_config(self):
|
|
41
46
|
"""Get vision configuration from unified config system."""
|
|
47
|
+
if self.config_manager is None:
|
|
48
|
+
# Return a minimal config object when config system is not available
|
|
49
|
+
class FallbackVisionConfig:
|
|
50
|
+
strategy = "disabled"
|
|
51
|
+
caption_provider = None
|
|
52
|
+
caption_model = None
|
|
53
|
+
fallback_chain = []
|
|
54
|
+
local_models_path = None
|
|
55
|
+
return FallbackVisionConfig()
|
|
42
56
|
return self.config_manager.config.vision
|
|
43
57
|
|
|
44
58
|
def create_description(self, image_path: str, user_prompt: str = None) -> str:
|
|
@@ -11,4 +11,4 @@ including when the package is installed from PyPI where pyproject.toml is not av
|
|
|
11
11
|
|
|
12
12
|
# Package version - update this when releasing new versions
|
|
13
13
|
# This must be manually synchronized with the version in pyproject.toml
|
|
14
|
-
__version__ = "2.
|
|
14
|
+
__version__ = "2.5.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractcore
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Unified interface to all LLM providers with essential infrastructure for tool calling, streaming, and model management
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
6
|
Maintainer-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
@@ -551,6 +551,10 @@ abstractcore --set-console-log-level NONE # Disable console logging
|
|
|
551
551
|
abstractcore --enable-file-logging # Save logs to files
|
|
552
552
|
abstractcore --enable-debug-logging # Full debug mode
|
|
553
553
|
|
|
554
|
+
# Configure vision for image analysis with text-only models
|
|
555
|
+
abstractcore --set-vision-provider ollama qwen2.5vl:7b
|
|
556
|
+
abstractcore --set-vision-provider lmstudio qwen/qwen3-vl-4b
|
|
557
|
+
|
|
554
558
|
# Set API keys as needed
|
|
555
559
|
abstractcore --set-api-key openai sk-your-key-here
|
|
556
560
|
abstractcore --set-api-key anthropic your-anthropic-key
|
|
@@ -20,9 +20,10 @@ abstractcore/architectures/enums.py
|
|
|
20
20
|
abstractcore/assets/architecture_formats.json
|
|
21
21
|
abstractcore/assets/model_capabilities.json
|
|
22
22
|
abstractcore/assets/session_schema.json
|
|
23
|
-
abstractcore/
|
|
24
|
-
abstractcore/
|
|
25
|
-
abstractcore/
|
|
23
|
+
abstractcore/config/__init__.py
|
|
24
|
+
abstractcore/config/main.py
|
|
25
|
+
abstractcore/config/manager.py
|
|
26
|
+
abstractcore/config/vision_config.py
|
|
26
27
|
abstractcore/core/__init__.py
|
|
27
28
|
abstractcore/core/enums.py
|
|
28
29
|
abstractcore/core/factory.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
|
-
abstractcore = abstractcore.
|
|
2
|
+
abstractcore = abstractcore.config.main:main
|
|
3
3
|
abstractcore-chat = abstractcore.utils.cli:main
|
|
4
|
-
abstractcore-config = abstractcore.
|
|
4
|
+
abstractcore-config = abstractcore.config.main:main
|
|
5
5
|
abstractcore-extractor = abstractcore.apps.extractor:main
|
|
6
6
|
abstractcore-judge = abstractcore.apps.judge:main
|
|
7
7
|
abstractcore-summarizer = abstractcore.apps.summarizer:main
|
|
@@ -61,8 +61,8 @@ Changelog = "https://github.com/lpalbou/AbstractCore/blob/main/CHANGELOG.md"
|
|
|
61
61
|
|
|
62
62
|
[project.scripts]
|
|
63
63
|
# Configuration CLI (manage AbstractCore settings, API keys, models)
|
|
64
|
-
abstractcore = "abstractcore.
|
|
65
|
-
abstractcore-config = "abstractcore.
|
|
64
|
+
abstractcore = "abstractcore.config.main:main"
|
|
65
|
+
abstractcore-config = "abstractcore.config.main:main"
|
|
66
66
|
|
|
67
67
|
# Interactive Chat CLI (REPL for LLM interaction)
|
|
68
68
|
abstractcore-chat = "abstractcore.utils.cli:main"
|
|
@@ -216,7 +216,7 @@ packages = [
|
|
|
216
216
|
"abstractcore.media.processors",
|
|
217
217
|
"abstractcore.media.handlers",
|
|
218
218
|
"abstractcore.media.utils",
|
|
219
|
-
"abstractcore.
|
|
219
|
+
"abstractcore.config"
|
|
220
220
|
]
|
|
221
221
|
|
|
222
222
|
[tool.setuptools.dynamic]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstractcore-2.4.8/abstractcore/cli → abstractcore-2.5.0/abstractcore/config}/vision_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|