abstractcore 2.6.0__tar.gz → 2.6.2__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.
Files changed (136) hide show
  1. {abstractcore-2.6.0 → abstractcore-2.6.2}/PKG-INFO +61 -1
  2. {abstractcore-2.6.0 → abstractcore-2.6.2}/README.md +60 -0
  3. abstractcore-2.6.2/abstractcore/config/__init__.py +33 -0
  4. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/config/manager.py +47 -0
  5. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/lmstudio_provider.py +8 -2
  6. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/ollama_provider.py +9 -2
  7. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/registry.py +9 -1
  8. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/version.py +1 -1
  9. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/PKG-INFO +61 -1
  10. abstractcore-2.6.0/abstractcore/config/__init__.py +0 -10
  11. {abstractcore-2.6.0 → abstractcore-2.6.2}/LICENSE +0 -0
  12. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/__init__.py +0 -0
  13. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/__init__.py +0 -0
  14. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/__main__.py +0 -0
  15. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/app_config_utils.py +0 -0
  16. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/deepsearch.py +0 -0
  17. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/extractor.py +0 -0
  18. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/intent.py +0 -0
  19. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/judge.py +0 -0
  20. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/apps/summarizer.py +0 -0
  21. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/architectures/__init__.py +0 -0
  22. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/architectures/detection.py +0 -0
  23. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/architectures/enums.py +0 -0
  24. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/assets/architecture_formats.json +0 -0
  25. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/assets/model_capabilities.json +0 -0
  26. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/assets/session_schema.json +0 -0
  27. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/__init__.py +0 -0
  28. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/analytics.py +0 -0
  29. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/cache.py +0 -0
  30. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/config.py +0 -0
  31. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/exceptions.py +0 -0
  32. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/glyph_processor.py +0 -0
  33. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/optimizer.py +0 -0
  34. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/orchestrator.py +0 -0
  35. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/pil_text_renderer.py +0 -0
  36. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/quality.py +0 -0
  37. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/text_formatter.py +0 -0
  38. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/compression/vision_compressor.py +0 -0
  39. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/config/main.py +0 -0
  40. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/config/vision_config.py +0 -0
  41. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/__init__.py +0 -0
  42. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/enums.py +0 -0
  43. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/factory.py +0 -0
  44. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/interface.py +0 -0
  45. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/retry.py +0 -0
  46. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/session.py +0 -0
  47. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/core/types.py +0 -0
  48. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/download.py +0 -0
  49. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/embeddings/__init__.py +0 -0
  50. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/embeddings/manager.py +0 -0
  51. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/embeddings/models.py +0 -0
  52. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/events/__init__.py +0 -0
  53. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/exceptions/__init__.py +0 -0
  54. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/__init__.py +0 -0
  55. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/auto_handler.py +0 -0
  56. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/base.py +0 -0
  57. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/capabilities.py +0 -0
  58. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/handlers/__init__.py +0 -0
  59. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/handlers/anthropic_handler.py +0 -0
  60. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/handlers/local_handler.py +0 -0
  61. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/handlers/openai_handler.py +0 -0
  62. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/__init__.py +0 -0
  63. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/direct_pdf_processor.py +0 -0
  64. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/glyph_pdf_processor.py +0 -0
  65. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/image_processor.py +0 -0
  66. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/office_processor.py +0 -0
  67. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/pdf_processor.py +0 -0
  68. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/processors/text_processor.py +0 -0
  69. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/types.py +0 -0
  70. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/utils/__init__.py +0 -0
  71. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/utils/image_scaler.py +0 -0
  72. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/media/vision_fallback.py +0 -0
  73. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/__init__.py +0 -0
  74. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/basic_deepsearch.py +0 -0
  75. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/basic_extractor.py +0 -0
  76. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/basic_intent.py +0 -0
  77. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/basic_judge.py +0 -0
  78. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/processing/basic_summarizer.py +0 -0
  79. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/__init__.py +0 -0
  80. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/anthropic_provider.py +0 -0
  81. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/base.py +0 -0
  82. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/huggingface_provider.py +0 -0
  83. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/mlx_provider.py +0 -0
  84. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/model_capabilities.py +0 -0
  85. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/openai_provider.py +0 -0
  86. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/providers/streaming.py +0 -0
  87. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/server/__init__.py +0 -0
  88. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/server/app.py +0 -0
  89. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/structured/__init__.py +0 -0
  90. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/structured/handler.py +0 -0
  91. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/structured/retry.py +0 -0
  92. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/__init__.py +0 -0
  93. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/common_tools.py +0 -0
  94. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/core.py +0 -0
  95. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/handler.py +0 -0
  96. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/parser.py +0 -0
  97. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/registry.py +0 -0
  98. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/syntax_rewriter.py +0 -0
  99. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/tools/tag_rewriter.py +0 -0
  100. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/__init__.py +0 -0
  101. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/cli.py +0 -0
  102. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/message_preprocessor.py +0 -0
  103. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/self_fixes.py +0 -0
  104. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/structured_logging.py +0 -0
  105. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/token_utils.py +0 -0
  106. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/trace_export.py +0 -0
  107. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore/utils/vlm_token_calculator.py +0 -0
  108. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/SOURCES.txt +0 -0
  109. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/dependency_links.txt +0 -0
  110. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/entry_points.txt +0 -0
  111. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/requires.txt +0 -0
  112. {abstractcore-2.6.0 → abstractcore-2.6.2}/abstractcore.egg-info/top_level.txt +0 -0
  113. {abstractcore-2.6.0 → abstractcore-2.6.2}/pyproject.toml +0 -0
  114. {abstractcore-2.6.0 → abstractcore-2.6.2}/setup.cfg +0 -0
  115. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_agentic_cli_compatibility.py +0 -0
  116. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_basic_session.py +0 -0
  117. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_complete_integration.py +0 -0
  118. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_comprehensive_events.py +0 -0
  119. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_core_components.py +0 -0
  120. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_enhanced_prompt.py +0 -0
  121. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_environment_variable_tool_call_tags.py +0 -0
  122. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_factory.py +0 -0
  123. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_final_accuracy.py +0 -0
  124. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_final_comprehensive.py +0 -0
  125. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_final_graceful_errors.py +0 -0
  126. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_graceful_fallback.py +0 -0
  127. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_import_debug.py +0 -0
  128. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_integrated_functionality.py +0 -0
  129. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_retry_observability.py +0 -0
  130. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_retry_strategy.py +0 -0
  131. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_seed_determinism.py +0 -0
  132. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_seed_temperature_basic.py +0 -0
  133. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_sensory_prompting.py +0 -0
  134. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_text_only_model_experience.py +0 -0
  135. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_unload_memory.py +0 -0
  136. {abstractcore-2.6.0 → abstractcore-2.6.2}/tests/test_user_scenario_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstractcore
3
- Version: 2.6.0
3
+ Version: 2.6.2
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>
@@ -795,6 +795,66 @@ summarizer document.pdf --provider anthropic --model claude-3-5-sonnet
795
795
 
796
796
  **Complete guide**: [Centralized Configuration](docs/centralized-config.md)
797
797
 
798
+ ### Environment Variables
799
+
800
+ AbstractCore supports environment variables for provider base URLs, enabling remote servers, Docker deployments, and non-standard ports:
801
+
802
+ ```bash
803
+ # Ollama on remote server
804
+ export OLLAMA_BASE_URL="http://192.168.1.100:11434"
805
+ # Alternative: OLLAMA_HOST is also supported
806
+ export OLLAMA_HOST="http://192.168.1.100:11434"
807
+
808
+ # LMStudio on non-standard port
809
+ export LMSTUDIO_BASE_URL="http://localhost:1235/v1"
810
+
811
+ # OpenAI-compatible proxy
812
+ export OPENAI_BASE_URL="https://api.portkey.ai/v1"
813
+
814
+ # Anthropic proxy
815
+ export ANTHROPIC_BASE_URL="https://api.portkey.ai/v1"
816
+ ```
817
+
818
+ **Priority**: Programmatic `base_url` parameter > Runtime configuration > Environment variable > Default value
819
+
820
+ **Provider discovery**: `get_all_providers_with_models()` automatically respects these environment variables when checking provider availability.
821
+
822
+ ### Programmatic Configuration
823
+
824
+ Configure provider settings at runtime without environment variables:
825
+
826
+ ```python
827
+ from abstractcore.config import configure_provider, get_provider_config, clear_provider_config
828
+ from abstractcore import create_llm
829
+
830
+ # Set provider base URL programmatically
831
+ configure_provider('ollama', base_url='http://192.168.1.100:11434')
832
+
833
+ # All future create_llm() calls automatically use the configured URL
834
+ llm = create_llm('ollama', model='llama3:8b') # Uses http://192.168.1.100:11434
835
+
836
+ # Query current configuration
837
+ config = get_provider_config('ollama')
838
+ print(config) # {'base_url': 'http://192.168.1.100:11434'}
839
+
840
+ # Clear configuration (revert to env var / default)
841
+ configure_provider('ollama', base_url=None)
842
+ # Or clear all providers
843
+ clear_provider_config()
844
+ ```
845
+
846
+ **Use Cases**:
847
+ - **Web UI Settings**: Configure providers through settings pages
848
+ - **Docker Startup**: Read from custom env vars and configure programmatically
849
+ - **Testing**: Set mock server URLs for integration tests
850
+ - **Multi-tenant**: Configure different base URLs per tenant
851
+
852
+ **Priority System**:
853
+ 1. Constructor parameter (highest): `create_llm("ollama", base_url="...")`
854
+ 2. Runtime configuration: `configure_provider('ollama', base_url="...")`
855
+ 3. Environment variable: `OLLAMA_BASE_URL`
856
+ 4. Default value (lowest): `http://localhost:11434`
857
+
798
858
  ## Documentation
799
859
 
800
860
  **📚 Complete Documentation:** [docs/](docs/) - Full documentation index and navigation guide
@@ -683,6 +683,66 @@ summarizer document.pdf --provider anthropic --model claude-3-5-sonnet
683
683
 
684
684
  **Complete guide**: [Centralized Configuration](docs/centralized-config.md)
685
685
 
686
+ ### Environment Variables
687
+
688
+ AbstractCore supports environment variables for provider base URLs, enabling remote servers, Docker deployments, and non-standard ports:
689
+
690
+ ```bash
691
+ # Ollama on remote server
692
+ export OLLAMA_BASE_URL="http://192.168.1.100:11434"
693
+ # Alternative: OLLAMA_HOST is also supported
694
+ export OLLAMA_HOST="http://192.168.1.100:11434"
695
+
696
+ # LMStudio on non-standard port
697
+ export LMSTUDIO_BASE_URL="http://localhost:1235/v1"
698
+
699
+ # OpenAI-compatible proxy
700
+ export OPENAI_BASE_URL="https://api.portkey.ai/v1"
701
+
702
+ # Anthropic proxy
703
+ export ANTHROPIC_BASE_URL="https://api.portkey.ai/v1"
704
+ ```
705
+
706
+ **Priority**: Programmatic `base_url` parameter > Runtime configuration > Environment variable > Default value
707
+
708
+ **Provider discovery**: `get_all_providers_with_models()` automatically respects these environment variables when checking provider availability.
709
+
710
+ ### Programmatic Configuration
711
+
712
+ Configure provider settings at runtime without environment variables:
713
+
714
+ ```python
715
+ from abstractcore.config import configure_provider, get_provider_config, clear_provider_config
716
+ from abstractcore import create_llm
717
+
718
+ # Set provider base URL programmatically
719
+ configure_provider('ollama', base_url='http://192.168.1.100:11434')
720
+
721
+ # All future create_llm() calls automatically use the configured URL
722
+ llm = create_llm('ollama', model='llama3:8b') # Uses http://192.168.1.100:11434
723
+
724
+ # Query current configuration
725
+ config = get_provider_config('ollama')
726
+ print(config) # {'base_url': 'http://192.168.1.100:11434'}
727
+
728
+ # Clear configuration (revert to env var / default)
729
+ configure_provider('ollama', base_url=None)
730
+ # Or clear all providers
731
+ clear_provider_config()
732
+ ```
733
+
734
+ **Use Cases**:
735
+ - **Web UI Settings**: Configure providers through settings pages
736
+ - **Docker Startup**: Read from custom env vars and configure programmatically
737
+ - **Testing**: Set mock server URLs for integration tests
738
+ - **Multi-tenant**: Configure different base URLs per tenant
739
+
740
+ **Priority System**:
741
+ 1. Constructor parameter (highest): `create_llm("ollama", base_url="...")`
742
+ 2. Runtime configuration: `configure_provider('ollama', base_url="...")`
743
+ 3. Environment variable: `OLLAMA_BASE_URL`
744
+ 4. Default value (lowest): `http://localhost:11434`
745
+
686
746
  ## Documentation
687
747
 
688
748
  **📚 Complete Documentation:** [docs/](docs/) - Full documentation index and navigation guide
@@ -0,0 +1,33 @@
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
+
11
+ def configure_provider(provider: str, **kwargs) -> None:
12
+ """Configure runtime settings for a provider."""
13
+ get_config_manager().configure_provider(provider, **kwargs)
14
+
15
+
16
+ def get_provider_config(provider: str) -> dict:
17
+ """Get runtime configuration for a provider."""
18
+ return get_config_manager().get_provider_config(provider)
19
+
20
+
21
+ def clear_provider_config(provider: str = None) -> None:
22
+ """Clear runtime provider configuration."""
23
+ get_config_manager().clear_provider_config(provider)
24
+
25
+
26
+ __all__ = [
27
+ 'handle_vision_commands',
28
+ 'add_vision_arguments',
29
+ 'get_config_manager',
30
+ 'configure_provider',
31
+ 'get_provider_config',
32
+ 'clear_provider_config'
33
+ ]
@@ -136,6 +136,7 @@ class ConfigurationManager:
136
136
  self.config_dir = Path.home() / ".abstractcore" / "config"
137
137
  self.config_file = self.config_dir / "abstractcore.json"
138
138
  self.config = self._load_config()
139
+ self._provider_config: Dict[str, Dict[str, Any]] = {} # Runtime config (not persisted)
139
140
 
140
141
  def _load_config(self) -> AbstractCoreConfig:
141
142
  """Load configuration from file or create default."""
@@ -437,6 +438,52 @@ class ConfigurationManager:
437
438
  """Check if local_files_only should be forced for transformers."""
438
439
  return self.config.offline.force_local_files_only
439
440
 
441
+ def configure_provider(self, provider: str, **kwargs) -> None:
442
+ """
443
+ Configure runtime settings for a provider.
444
+
445
+ Args:
446
+ provider: Provider name ('ollama', 'lmstudio', 'openai', 'anthropic')
447
+ **kwargs: Configuration options (base_url, timeout, etc.)
448
+
449
+ Example:
450
+ configure_provider('ollama', base_url='http://192.168.1.100:11434')
451
+ """
452
+ provider = provider.lower()
453
+ if provider not in self._provider_config:
454
+ self._provider_config[provider] = {}
455
+
456
+ for key, value in kwargs.items():
457
+ if value is None:
458
+ # Remove config (revert to env var / default)
459
+ self._provider_config[provider].pop(key, None)
460
+ else:
461
+ self._provider_config[provider][key] = value
462
+
463
+ def get_provider_config(self, provider: str) -> Dict[str, Any]:
464
+ """
465
+ Get runtime configuration for a provider.
466
+
467
+ Args:
468
+ provider: Provider name
469
+
470
+ Returns:
471
+ Dict with configured settings, or empty dict if no config
472
+ """
473
+ return self._provider_config.get(provider.lower(), {}).copy()
474
+
475
+ def clear_provider_config(self, provider: Optional[str] = None) -> None:
476
+ """
477
+ Clear runtime provider configuration.
478
+
479
+ Args:
480
+ provider: Provider name, or None to clear all
481
+ """
482
+ if provider is None:
483
+ self._provider_config.clear()
484
+ else:
485
+ self._provider_config.pop(provider.lower(), None)
486
+
440
487
 
441
488
  # Global instance
442
489
  _config_manager = None
@@ -2,6 +2,7 @@
2
2
  LM Studio provider implementation (OpenAI-compatible API).
3
3
  """
4
4
 
5
+ import os
5
6
  import httpx
6
7
  import json
7
8
  import time
@@ -23,14 +24,19 @@ from ..events import EventType
23
24
  class LMStudioProvider(BaseProvider):
24
25
  """LM Studio provider using OpenAI-compatible API"""
25
26
 
26
- def __init__(self, model: str = "local-model", base_url: str = "http://localhost:1234/v1", **kwargs):
27
+ def __init__(self, model: str = "local-model", base_url: Optional[str] = None, **kwargs):
27
28
  super().__init__(model, **kwargs)
28
29
  self.provider = "lmstudio"
29
30
 
30
31
  # Initialize tool handler
31
32
  self.tool_handler = UniversalToolHandler(model)
32
33
 
33
- self.base_url = base_url.rstrip('/')
34
+ # Base URL priority: parameter > LMSTUDIO_BASE_URL > default
35
+ self.base_url = (
36
+ base_url or
37
+ os.getenv("LMSTUDIO_BASE_URL") or
38
+ "http://localhost:1234/v1"
39
+ ).rstrip('/')
34
40
 
35
41
  # Get timeout value - None means unlimited timeout
36
42
  timeout_value = getattr(self, '_timeout', None)
@@ -3,6 +3,7 @@ Ollama provider implementation.
3
3
  """
4
4
 
5
5
  import json
6
+ import os
6
7
  import httpx
7
8
  import time
8
9
  from typing import List, Dict, Any, Optional, Union, Iterator, AsyncIterator, Type
@@ -23,11 +24,17 @@ from ..events import EventType
23
24
  class OllamaProvider(BaseProvider):
24
25
  """Ollama provider for local models with full integration"""
25
26
 
26
- def __init__(self, model: str = "qwen3:4b-instruct-2507-q4_K_M", base_url: str = "http://localhost:11434", **kwargs):
27
+ def __init__(self, model: str = "qwen3:4b-instruct-2507-q4_K_M", base_url: Optional[str] = None, **kwargs):
27
28
  super().__init__(model, **kwargs)
28
29
  self.provider = "ollama"
29
30
 
30
- self.base_url = base_url.rstrip('/')
31
+ # Base URL priority: parameter > OLLAMA_BASE_URL > OLLAMA_HOST > default
32
+ self.base_url = (
33
+ base_url or
34
+ os.getenv("OLLAMA_BASE_URL") or
35
+ os.getenv("OLLAMA_HOST") or
36
+ "http://localhost:11434"
37
+ ).rstrip('/')
31
38
  self.client = httpx.Client(timeout=self._timeout)
32
39
  self._async_client = None # Lazy-loaded async client
33
40
 
@@ -354,6 +354,8 @@ class ProviderRegistry:
354
354
 
355
355
  This is used by the factory to create provider instances.
356
356
  """
357
+ from ..config import get_provider_config
358
+
357
359
  provider_info = self.get_provider_info(provider_name)
358
360
  if not provider_info:
359
361
  available_providers = ", ".join(self.list_provider_names())
@@ -362,8 +364,14 @@ class ProviderRegistry:
362
364
  provider_class = self.get_provider_class(provider_name)
363
365
  model = model or provider_info.default_model
364
366
 
367
+ # Get runtime config for this provider
368
+ runtime_config = get_provider_config(provider_name)
369
+
370
+ # Merge: runtime_config < kwargs (user kwargs take precedence)
371
+ merged_kwargs = {**runtime_config, **kwargs}
372
+
365
373
  try:
366
- return provider_class(model=model, **kwargs)
374
+ return provider_class(model=model, **merged_kwargs)
367
375
  except ImportError as e:
368
376
  # Re-raise import errors with helpful message
369
377
  if provider_info.installation_extras:
@@ -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.6.0"
14
+ __version__ = "2.6.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstractcore
3
- Version: 2.6.0
3
+ Version: 2.6.2
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>
@@ -795,6 +795,66 @@ summarizer document.pdf --provider anthropic --model claude-3-5-sonnet
795
795
 
796
796
  **Complete guide**: [Centralized Configuration](docs/centralized-config.md)
797
797
 
798
+ ### Environment Variables
799
+
800
+ AbstractCore supports environment variables for provider base URLs, enabling remote servers, Docker deployments, and non-standard ports:
801
+
802
+ ```bash
803
+ # Ollama on remote server
804
+ export OLLAMA_BASE_URL="http://192.168.1.100:11434"
805
+ # Alternative: OLLAMA_HOST is also supported
806
+ export OLLAMA_HOST="http://192.168.1.100:11434"
807
+
808
+ # LMStudio on non-standard port
809
+ export LMSTUDIO_BASE_URL="http://localhost:1235/v1"
810
+
811
+ # OpenAI-compatible proxy
812
+ export OPENAI_BASE_URL="https://api.portkey.ai/v1"
813
+
814
+ # Anthropic proxy
815
+ export ANTHROPIC_BASE_URL="https://api.portkey.ai/v1"
816
+ ```
817
+
818
+ **Priority**: Programmatic `base_url` parameter > Runtime configuration > Environment variable > Default value
819
+
820
+ **Provider discovery**: `get_all_providers_with_models()` automatically respects these environment variables when checking provider availability.
821
+
822
+ ### Programmatic Configuration
823
+
824
+ Configure provider settings at runtime without environment variables:
825
+
826
+ ```python
827
+ from abstractcore.config import configure_provider, get_provider_config, clear_provider_config
828
+ from abstractcore import create_llm
829
+
830
+ # Set provider base URL programmatically
831
+ configure_provider('ollama', base_url='http://192.168.1.100:11434')
832
+
833
+ # All future create_llm() calls automatically use the configured URL
834
+ llm = create_llm('ollama', model='llama3:8b') # Uses http://192.168.1.100:11434
835
+
836
+ # Query current configuration
837
+ config = get_provider_config('ollama')
838
+ print(config) # {'base_url': 'http://192.168.1.100:11434'}
839
+
840
+ # Clear configuration (revert to env var / default)
841
+ configure_provider('ollama', base_url=None)
842
+ # Or clear all providers
843
+ clear_provider_config()
844
+ ```
845
+
846
+ **Use Cases**:
847
+ - **Web UI Settings**: Configure providers through settings pages
848
+ - **Docker Startup**: Read from custom env vars and configure programmatically
849
+ - **Testing**: Set mock server URLs for integration tests
850
+ - **Multi-tenant**: Configure different base URLs per tenant
851
+
852
+ **Priority System**:
853
+ 1. Constructor parameter (highest): `create_llm("ollama", base_url="...")`
854
+ 2. Runtime configuration: `configure_provider('ollama', base_url="...")`
855
+ 3. Environment variable: `OLLAMA_BASE_URL`
856
+ 4. Default value (lowest): `http://localhost:11434`
857
+
798
858
  ## Documentation
799
859
 
800
860
  **📚 Complete Documentation:** [docs/](docs/) - Full documentation index and navigation guide
@@ -1,10 +0,0 @@
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']
File without changes
File without changes