abstractcore 2.5.3__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.5.3 → abstractcore-2.6.2}/PKG-INFO +162 -4
  2. {abstractcore-2.5.3 → abstractcore-2.6.2}/README.md +155 -3
  3. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/__init__.py +7 -1
  4. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/architectures/detection.py +2 -2
  5. abstractcore-2.6.2/abstractcore/config/__init__.py +33 -0
  6. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/config/manager.py +47 -0
  7. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/retry.py +2 -2
  8. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/session.py +132 -1
  9. abstractcore-2.6.2/abstractcore/download.py +253 -0
  10. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/embeddings/manager.py +2 -2
  11. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/events/__init__.py +112 -1
  12. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/exceptions/__init__.py +49 -2
  13. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/office_processor.py +2 -2
  14. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/utils/image_scaler.py +2 -2
  15. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/vision_fallback.py +2 -2
  16. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/anthropic_provider.py +200 -6
  17. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/base.py +100 -5
  18. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/lmstudio_provider.py +254 -4
  19. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/ollama_provider.py +253 -4
  20. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/openai_provider.py +258 -6
  21. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/registry.py +9 -1
  22. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/streaming.py +2 -2
  23. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/common_tools.py +2 -2
  24. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/handler.py +2 -2
  25. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/parser.py +2 -2
  26. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/registry.py +2 -2
  27. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/syntax_rewriter.py +2 -2
  28. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/tag_rewriter.py +3 -3
  29. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/self_fixes.py +2 -2
  30. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/version.py +1 -1
  31. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/PKG-INFO +162 -4
  32. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/SOURCES.txt +1 -0
  33. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/requires.txt +9 -0
  34. {abstractcore-2.5.3 → abstractcore-2.6.2}/pyproject.toml +12 -0
  35. abstractcore-2.5.3/abstractcore/config/__init__.py +0 -10
  36. {abstractcore-2.5.3 → abstractcore-2.6.2}/LICENSE +0 -0
  37. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/__init__.py +0 -0
  38. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/__main__.py +0 -0
  39. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/app_config_utils.py +0 -0
  40. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/deepsearch.py +0 -0
  41. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/extractor.py +0 -0
  42. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/intent.py +0 -0
  43. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/judge.py +0 -0
  44. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/apps/summarizer.py +0 -0
  45. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/architectures/__init__.py +0 -0
  46. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/architectures/enums.py +0 -0
  47. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/assets/architecture_formats.json +0 -0
  48. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/assets/model_capabilities.json +0 -0
  49. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/assets/session_schema.json +0 -0
  50. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/__init__.py +0 -0
  51. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/analytics.py +0 -0
  52. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/cache.py +0 -0
  53. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/config.py +0 -0
  54. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/exceptions.py +0 -0
  55. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/glyph_processor.py +0 -0
  56. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/optimizer.py +0 -0
  57. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/orchestrator.py +0 -0
  58. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/pil_text_renderer.py +0 -0
  59. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/quality.py +0 -0
  60. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/text_formatter.py +0 -0
  61. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/compression/vision_compressor.py +0 -0
  62. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/config/main.py +0 -0
  63. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/config/vision_config.py +0 -0
  64. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/__init__.py +0 -0
  65. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/enums.py +0 -0
  66. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/factory.py +0 -0
  67. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/interface.py +0 -0
  68. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/core/types.py +0 -0
  69. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/embeddings/__init__.py +0 -0
  70. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/embeddings/models.py +0 -0
  71. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/__init__.py +0 -0
  72. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/auto_handler.py +0 -0
  73. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/base.py +0 -0
  74. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/capabilities.py +0 -0
  75. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/handlers/__init__.py +0 -0
  76. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/handlers/anthropic_handler.py +0 -0
  77. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/handlers/local_handler.py +0 -0
  78. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/handlers/openai_handler.py +0 -0
  79. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/__init__.py +0 -0
  80. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/direct_pdf_processor.py +0 -0
  81. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/glyph_pdf_processor.py +0 -0
  82. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/image_processor.py +0 -0
  83. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/pdf_processor.py +0 -0
  84. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/processors/text_processor.py +0 -0
  85. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/types.py +0 -0
  86. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/media/utils/__init__.py +0 -0
  87. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/__init__.py +0 -0
  88. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/basic_deepsearch.py +0 -0
  89. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/basic_extractor.py +0 -0
  90. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/basic_intent.py +0 -0
  91. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/basic_judge.py +0 -0
  92. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/processing/basic_summarizer.py +0 -0
  93. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/__init__.py +0 -0
  94. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/huggingface_provider.py +0 -0
  95. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/mlx_provider.py +0 -0
  96. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/providers/model_capabilities.py +0 -0
  97. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/server/__init__.py +0 -0
  98. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/server/app.py +0 -0
  99. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/structured/__init__.py +0 -0
  100. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/structured/handler.py +0 -0
  101. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/structured/retry.py +0 -0
  102. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/__init__.py +0 -0
  103. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/tools/core.py +0 -0
  104. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/__init__.py +0 -0
  105. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/cli.py +0 -0
  106. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/message_preprocessor.py +0 -0
  107. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/structured_logging.py +0 -0
  108. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/token_utils.py +0 -0
  109. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/trace_export.py +0 -0
  110. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore/utils/vlm_token_calculator.py +0 -0
  111. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/dependency_links.txt +0 -0
  112. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/entry_points.txt +0 -0
  113. {abstractcore-2.5.3 → abstractcore-2.6.2}/abstractcore.egg-info/top_level.txt +0 -0
  114. {abstractcore-2.5.3 → abstractcore-2.6.2}/setup.cfg +0 -0
  115. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_agentic_cli_compatibility.py +0 -0
  116. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_basic_session.py +0 -0
  117. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_complete_integration.py +0 -0
  118. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_comprehensive_events.py +0 -0
  119. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_core_components.py +0 -0
  120. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_enhanced_prompt.py +0 -0
  121. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_environment_variable_tool_call_tags.py +0 -0
  122. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_factory.py +0 -0
  123. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_final_accuracy.py +0 -0
  124. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_final_comprehensive.py +0 -0
  125. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_final_graceful_errors.py +0 -0
  126. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_graceful_fallback.py +0 -0
  127. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_import_debug.py +0 -0
  128. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_integrated_functionality.py +0 -0
  129. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_retry_observability.py +0 -0
  130. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_retry_strategy.py +0 -0
  131. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_seed_determinism.py +0 -0
  132. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_seed_temperature_basic.py +0 -0
  133. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_sensory_prompting.py +0 -0
  134. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_text_only_model_experience.py +0 -0
  135. {abstractcore-2.5.3 → abstractcore-2.6.2}/tests/test_unload_memory.py +0 -0
  136. {abstractcore-2.5.3 → 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.5.3
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>
@@ -67,12 +67,18 @@ Provides-Extra: api-providers
67
67
  Requires-Dist: abstractcore[anthropic,openai]; extra == "api-providers"
68
68
  Provides-Extra: local-providers
69
69
  Requires-Dist: abstractcore[lmstudio,mlx,ollama]; extra == "local-providers"
70
+ Provides-Extra: local-providers-non-mlx
71
+ Requires-Dist: abstractcore[lmstudio,ollama]; extra == "local-providers-non-mlx"
70
72
  Provides-Extra: heavy-providers
71
73
  Requires-Dist: abstractcore[huggingface]; extra == "heavy-providers"
72
74
  Provides-Extra: all-providers
73
75
  Requires-Dist: abstractcore[anthropic,embeddings,huggingface,lmstudio,mlx,ollama,openai]; extra == "all-providers"
76
+ Provides-Extra: all-providers-non-mlx
77
+ Requires-Dist: abstractcore[anthropic,embeddings,huggingface,lmstudio,ollama,openai]; extra == "all-providers-non-mlx"
74
78
  Provides-Extra: all
75
79
  Requires-Dist: abstractcore[anthropic,compression,dev,docs,embeddings,huggingface,lmstudio,media,mlx,ollama,openai,processing,server,test,tools]; extra == "all"
80
+ Provides-Extra: all-non-mlx
81
+ Requires-Dist: abstractcore[anthropic,compression,dev,docs,embeddings,huggingface,lmstudio,media,ollama,openai,processing,server,test,tools]; extra == "all-non-mlx"
76
82
  Provides-Extra: lightweight
77
83
  Requires-Dist: abstractcore[anthropic,compression,embeddings,lmstudio,media,ollama,openai,processing,server,tools]; extra == "lightweight"
78
84
  Provides-Extra: dev
@@ -120,7 +126,11 @@ A unified Python library for interaction with multiple Large Language Model (LLM
120
126
  ### Installation
121
127
 
122
128
  ```bash
129
+ # macOS/Apple Silicon (includes MLX)
123
130
  pip install abstractcore[all]
131
+
132
+ # Linux/Windows (excludes MLX)
133
+ pip install abstractcore[all-non-mlx]
124
134
  ```
125
135
 
126
136
  ### Basic Usage
@@ -311,6 +321,69 @@ export_traces(traces, format='markdown', file_path='workflow_trace.md')
311
321
 
312
322
  [Learn more about Interaction Tracing](docs/interaction-tracing.md)
313
323
 
324
+ ### Async/Await Support
325
+
326
+ Execute concurrent LLM requests for batch operations, multi-provider comparisons, or non-blocking web applications. **Production-ready with validated 6-7.5x performance improvement** for concurrent requests.
327
+
328
+ ```python
329
+ import asyncio
330
+ from abstractcore import create_llm
331
+
332
+ async def main():
333
+ llm = create_llm("openai", model="gpt-4o-mini")
334
+
335
+ # Execute 3 requests concurrently (6-7x faster!)
336
+ tasks = [
337
+ llm.agenerate(f"Summarize {topic}")
338
+ for topic in ["Python", "JavaScript", "Rust"]
339
+ ]
340
+ responses = await asyncio.gather(*tasks)
341
+
342
+ for response in responses:
343
+ print(response.content)
344
+
345
+ asyncio.run(main())
346
+ ```
347
+
348
+ **Performance (Validated with Real Testing):**
349
+ - **Ollama**: 7.5x faster for concurrent requests
350
+ - **LMStudio**: 6.5x faster for concurrent requests
351
+ - **OpenAI**: 6.0x faster for concurrent requests
352
+ - **Anthropic**: 7.4x faster for concurrent requests
353
+ - **Average**: ~7x speedup across all providers
354
+
355
+ **Native Async vs Fallback:**
356
+ - **Native async** (httpx.AsyncClient): Ollama, LMStudio, OpenAI, Anthropic
357
+ - **Fallback** (asyncio.to_thread): MLX, HuggingFace
358
+ - All providers work seamlessly - fallback keeps event loop responsive
359
+
360
+ **Use Cases:**
361
+ - Batch operations with 6-7x speedup via parallel execution
362
+ - Multi-provider comparisons (query OpenAI and Anthropic simultaneously)
363
+ - FastAPI/async web frameworks integration
364
+ - Session async for conversation management
365
+
366
+ **Works with:**
367
+ - All 6 providers (OpenAI, Anthropic, Ollama, LMStudio, MLX, HuggingFace)
368
+ - Streaming via `async for chunk in llm.agenerate(..., stream=True)`
369
+ - Sessions via `await session.agenerate(...)`
370
+ - Zero breaking changes to sync API
371
+
372
+ **Learn async patterns:**
373
+
374
+ AbstractCore includes an educational [async CLI demo](examples/async_cli_demo.py) that demonstrates 8 core async/await patterns:
375
+ - Event-driven progress with GlobalEventBus
376
+ - Parallel tool execution with asyncio.gather()
377
+ - Proper async streaming pattern (await first, then async for)
378
+ - Non-blocking animations and user input
379
+
380
+ ```bash
381
+ # Try the educational async demo
382
+ python examples/async_cli_demo.py --provider ollama --model qwen3:4b --stream
383
+ ```
384
+
385
+ [Learn more in CLI docs](docs/acore-cli.md#async-cli-demo-educational-reference)
386
+
314
387
  ### Media Handling
315
388
 
316
389
  AbstractCore provides unified media handling across all providers with automatic resolution optimization. Upload images, PDFs, and documents using the same simple API regardless of your provider.
@@ -408,7 +481,8 @@ if response.metadata and response.metadata.get('compression_used'):
408
481
 
409
482
  - **Offline-First Design**: Built primarily for open source LLMs with full offline capability. Download once, run forever without internet access
410
483
  - **Provider Agnostic**: Seamlessly switch between OpenAI, Anthropic, Ollama, LMStudio, MLX, HuggingFace
411
- - **Interaction Tracing**: Complete LLM observability with programmatic access to prompts, responses, tokens, and timing for debugging and compliance
484
+ - **Async/Await Support** NEW in v2.6.0: Native async support for concurrent requests with `asyncio.gather()` - works with all 6 providers
485
+ - **Interaction Tracing**: Complete LLM observability with programmatic access to prompts, responses, tokens, timing, and trace correlation for debugging, trust, and compliance
412
486
  - **Glyph Visual-Text Compression**: Revolutionary compression system that renders text as optimized images for 3-4x token compression and faster inference
413
487
  - **Centralized Configuration**: Global defaults and app-specific preferences at `~/.abstractcore/config/abstractcore.json`
414
488
  - **Intelligent Media Handling**: Upload images, PDFs, and documents with automatic maximum resolution optimization
@@ -522,7 +596,7 @@ python -m abstractcore.utils.cli --provider anthropic --model claude-3-5-haiku-l
522
596
 
523
597
  ## Built-in Applications (Ready-to-Use CLI Tools)
524
598
 
525
- AbstractCore includes **four specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
599
+ AbstractCore includes **five specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
526
600
 
527
601
  ### Available Applications
528
602
 
@@ -532,6 +606,7 @@ AbstractCore includes **four specialized command-line applications** for common
532
606
  | **Extractor** | Entity and relationship extraction | `extractor` |
533
607
  | **Judge** | Text evaluation and scoring | `judge` |
534
608
  | **Intent Analyzer** | Psychological intent analysis & deception detection | `intent` |
609
+ | **DeepSearch** | Autonomous multi-stage research with web search | `deepsearch` |
535
610
 
536
611
  ### Quick Usage Examples
537
612
 
@@ -555,6 +630,11 @@ judge proposal.md --custom-criteria has_examples,covers_risks --output assessmen
555
630
  intent conversation.txt --focus-participant user --depth comprehensive
556
631
  intent email.txt --format plain --context document --verbose
557
632
  intent chat_log.json --conversation-mode --provider lmstudio --model qwen/qwen3-30b-a3b-2507
633
+
634
+ # Autonomous research with web search and reflexive refinement
635
+ deepsearch "What are the latest advances in quantum computing?" --depth comprehensive
636
+ deepsearch "AI impact on healthcare" --focus "diagnosis,treatment,ethics" --reflexive
637
+ deepsearch "sustainable energy 2025" --max-sources 25 --provider openai --model gpt-4o-mini
558
638
  ```
559
639
 
560
640
  ### Installation & Setup
@@ -567,9 +647,10 @@ pip install abstractcore[all]
567
647
 
568
648
  # Apps are immediately available
569
649
  summarizer --help
570
- extractor --help
650
+ extractor --help
571
651
  judge --help
572
652
  intent --help
653
+ deepsearch --help
573
654
  ```
574
655
 
575
656
  ### Alternative Usage Methods
@@ -580,12 +661,14 @@ summarizer document.txt
580
661
  extractor report.pdf
581
662
  judge essay.md
582
663
  intent conversation.txt
664
+ deepsearch "your research query"
583
665
 
584
666
  # Method 2: Via Python module
585
667
  python -m abstractcore.apps summarizer document.txt
586
668
  python -m abstractcore.apps extractor report.pdf
587
669
  python -m abstractcore.apps judge essay.md
588
670
  python -m abstractcore.apps intent conversation.txt
671
+ python -m abstractcore.apps deepsearch "your research query"
589
672
  ```
590
673
 
591
674
  ### Key Parameters
@@ -633,6 +716,7 @@ Each application has documentation with examples and usage information:
633
716
  - **[Extractor Guide](docs/apps/basic-extractor.md)** - Entity and relationship extraction
634
717
  - **[Intent Analyzer Guide](docs/apps/basic-intent.md)** - Psychological intent analysis and deception detection
635
718
  - **[Judge Guide](docs/apps/basic-judge.md)** - Text evaluation and scoring systems
719
+ - **[DeepSearch Guide](docs/apps/basic-deepsearch.md)** - Autonomous multi-stage research with web search
636
720
 
637
721
  **When to use the apps:**
638
722
  - Processing documents without writing code
@@ -711,6 +795,66 @@ summarizer document.pdf --provider anthropic --model claude-3-5-sonnet
711
795
 
712
796
  **Complete guide**: [Centralized Configuration](docs/centralized-config.md)
713
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
+
714
858
  ## Documentation
715
859
 
716
860
  **📚 Complete Documentation:** [docs/](docs/) - Full documentation index and navigation guide
@@ -878,6 +1022,9 @@ pip install abstractcore[media]
878
1022
  pip install abstractcore[openai]
879
1023
  pip install abstractcore[anthropic]
880
1024
  pip install abstractcore[ollama]
1025
+ pip install abstractcore[lmstudio]
1026
+ pip install abstractcore[huggingface]
1027
+ pip install abstractcore[mlx] # macOS/Apple Silicon only
881
1028
 
882
1029
  # With server support
883
1030
  pip install abstractcore[server]
@@ -887,6 +1034,16 @@ pip install abstractcore[embeddings]
887
1034
 
888
1035
  # Everything (recommended)
889
1036
  pip install abstractcore[all]
1037
+
1038
+ # Cross-platform (all except MLX - for Linux/Windows)
1039
+ pip install abstractcore[all-non-mlx]
1040
+
1041
+ # Provider groups
1042
+ pip install abstractcore[all-providers] # All providers (includes MLX)
1043
+ pip install abstractcore[all-providers-non-mlx] # All providers except MLX
1044
+ pip install abstractcore[local-providers] # Ollama, LMStudio, MLX
1045
+ pip install abstractcore[local-providers-non-mlx] # Ollama, LMStudio only
1046
+ pip install abstractcore[api-providers] # OpenAI, Anthropic
890
1047
  ```
891
1048
 
892
1049
  **Media processing extras:**
@@ -917,6 +1074,7 @@ All tests passing as of October 12th, 2025.
917
1074
  ## Quick Links
918
1075
 
919
1076
  - **[📚 Documentation Index](docs/)** - Complete documentation navigation guide
1077
+ - **[🔍 Interaction Tracing](docs/interaction-tracing.md)** - LLM observability and debugging ⭐ NEW
920
1078
  - **[Getting Started](docs/getting-started.md)** - 5-minute quick start
921
1079
  - **[⚙️ Prerequisites](docs/prerequisites.md)** - Provider setup (OpenAI, Anthropic, Ollama, etc.)
922
1080
  - **[📖 Python API](docs/api-reference.md)** - Complete Python API reference
@@ -14,7 +14,11 @@ A unified Python library for interaction with multiple Large Language Model (LLM
14
14
  ### Installation
15
15
 
16
16
  ```bash
17
+ # macOS/Apple Silicon (includes MLX)
17
18
  pip install abstractcore[all]
19
+
20
+ # Linux/Windows (excludes MLX)
21
+ pip install abstractcore[all-non-mlx]
18
22
  ```
19
23
 
20
24
  ### Basic Usage
@@ -205,6 +209,69 @@ export_traces(traces, format='markdown', file_path='workflow_trace.md')
205
209
 
206
210
  [Learn more about Interaction Tracing](docs/interaction-tracing.md)
207
211
 
212
+ ### Async/Await Support
213
+
214
+ Execute concurrent LLM requests for batch operations, multi-provider comparisons, or non-blocking web applications. **Production-ready with validated 6-7.5x performance improvement** for concurrent requests.
215
+
216
+ ```python
217
+ import asyncio
218
+ from abstractcore import create_llm
219
+
220
+ async def main():
221
+ llm = create_llm("openai", model="gpt-4o-mini")
222
+
223
+ # Execute 3 requests concurrently (6-7x faster!)
224
+ tasks = [
225
+ llm.agenerate(f"Summarize {topic}")
226
+ for topic in ["Python", "JavaScript", "Rust"]
227
+ ]
228
+ responses = await asyncio.gather(*tasks)
229
+
230
+ for response in responses:
231
+ print(response.content)
232
+
233
+ asyncio.run(main())
234
+ ```
235
+
236
+ **Performance (Validated with Real Testing):**
237
+ - **Ollama**: 7.5x faster for concurrent requests
238
+ - **LMStudio**: 6.5x faster for concurrent requests
239
+ - **OpenAI**: 6.0x faster for concurrent requests
240
+ - **Anthropic**: 7.4x faster for concurrent requests
241
+ - **Average**: ~7x speedup across all providers
242
+
243
+ **Native Async vs Fallback:**
244
+ - **Native async** (httpx.AsyncClient): Ollama, LMStudio, OpenAI, Anthropic
245
+ - **Fallback** (asyncio.to_thread): MLX, HuggingFace
246
+ - All providers work seamlessly - fallback keeps event loop responsive
247
+
248
+ **Use Cases:**
249
+ - Batch operations with 6-7x speedup via parallel execution
250
+ - Multi-provider comparisons (query OpenAI and Anthropic simultaneously)
251
+ - FastAPI/async web frameworks integration
252
+ - Session async for conversation management
253
+
254
+ **Works with:**
255
+ - All 6 providers (OpenAI, Anthropic, Ollama, LMStudio, MLX, HuggingFace)
256
+ - Streaming via `async for chunk in llm.agenerate(..., stream=True)`
257
+ - Sessions via `await session.agenerate(...)`
258
+ - Zero breaking changes to sync API
259
+
260
+ **Learn async patterns:**
261
+
262
+ AbstractCore includes an educational [async CLI demo](examples/async_cli_demo.py) that demonstrates 8 core async/await patterns:
263
+ - Event-driven progress with GlobalEventBus
264
+ - Parallel tool execution with asyncio.gather()
265
+ - Proper async streaming pattern (await first, then async for)
266
+ - Non-blocking animations and user input
267
+
268
+ ```bash
269
+ # Try the educational async demo
270
+ python examples/async_cli_demo.py --provider ollama --model qwen3:4b --stream
271
+ ```
272
+
273
+ [Learn more in CLI docs](docs/acore-cli.md#async-cli-demo-educational-reference)
274
+
208
275
  ### Media Handling
209
276
 
210
277
  AbstractCore provides unified media handling across all providers with automatic resolution optimization. Upload images, PDFs, and documents using the same simple API regardless of your provider.
@@ -302,7 +369,8 @@ if response.metadata and response.metadata.get('compression_used'):
302
369
 
303
370
  - **Offline-First Design**: Built primarily for open source LLMs with full offline capability. Download once, run forever without internet access
304
371
  - **Provider Agnostic**: Seamlessly switch between OpenAI, Anthropic, Ollama, LMStudio, MLX, HuggingFace
305
- - **Interaction Tracing**: Complete LLM observability with programmatic access to prompts, responses, tokens, and timing for debugging and compliance
372
+ - **Async/Await Support** NEW in v2.6.0: Native async support for concurrent requests with `asyncio.gather()` - works with all 6 providers
373
+ - **Interaction Tracing**: Complete LLM observability with programmatic access to prompts, responses, tokens, timing, and trace correlation for debugging, trust, and compliance
306
374
  - **Glyph Visual-Text Compression**: Revolutionary compression system that renders text as optimized images for 3-4x token compression and faster inference
307
375
  - **Centralized Configuration**: Global defaults and app-specific preferences at `~/.abstractcore/config/abstractcore.json`
308
376
  - **Intelligent Media Handling**: Upload images, PDFs, and documents with automatic maximum resolution optimization
@@ -416,7 +484,7 @@ python -m abstractcore.utils.cli --provider anthropic --model claude-3-5-haiku-l
416
484
 
417
485
  ## Built-in Applications (Ready-to-Use CLI Tools)
418
486
 
419
- AbstractCore includes **four specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
487
+ AbstractCore includes **five specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
420
488
 
421
489
  ### Available Applications
422
490
 
@@ -426,6 +494,7 @@ AbstractCore includes **four specialized command-line applications** for common
426
494
  | **Extractor** | Entity and relationship extraction | `extractor` |
427
495
  | **Judge** | Text evaluation and scoring | `judge` |
428
496
  | **Intent Analyzer** | Psychological intent analysis & deception detection | `intent` |
497
+ | **DeepSearch** | Autonomous multi-stage research with web search | `deepsearch` |
429
498
 
430
499
  ### Quick Usage Examples
431
500
 
@@ -449,6 +518,11 @@ judge proposal.md --custom-criteria has_examples,covers_risks --output assessmen
449
518
  intent conversation.txt --focus-participant user --depth comprehensive
450
519
  intent email.txt --format plain --context document --verbose
451
520
  intent chat_log.json --conversation-mode --provider lmstudio --model qwen/qwen3-30b-a3b-2507
521
+
522
+ # Autonomous research with web search and reflexive refinement
523
+ deepsearch "What are the latest advances in quantum computing?" --depth comprehensive
524
+ deepsearch "AI impact on healthcare" --focus "diagnosis,treatment,ethics" --reflexive
525
+ deepsearch "sustainable energy 2025" --max-sources 25 --provider openai --model gpt-4o-mini
452
526
  ```
453
527
 
454
528
  ### Installation & Setup
@@ -461,9 +535,10 @@ pip install abstractcore[all]
461
535
 
462
536
  # Apps are immediately available
463
537
  summarizer --help
464
- extractor --help
538
+ extractor --help
465
539
  judge --help
466
540
  intent --help
541
+ deepsearch --help
467
542
  ```
468
543
 
469
544
  ### Alternative Usage Methods
@@ -474,12 +549,14 @@ summarizer document.txt
474
549
  extractor report.pdf
475
550
  judge essay.md
476
551
  intent conversation.txt
552
+ deepsearch "your research query"
477
553
 
478
554
  # Method 2: Via Python module
479
555
  python -m abstractcore.apps summarizer document.txt
480
556
  python -m abstractcore.apps extractor report.pdf
481
557
  python -m abstractcore.apps judge essay.md
482
558
  python -m abstractcore.apps intent conversation.txt
559
+ python -m abstractcore.apps deepsearch "your research query"
483
560
  ```
484
561
 
485
562
  ### Key Parameters
@@ -527,6 +604,7 @@ Each application has documentation with examples and usage information:
527
604
  - **[Extractor Guide](docs/apps/basic-extractor.md)** - Entity and relationship extraction
528
605
  - **[Intent Analyzer Guide](docs/apps/basic-intent.md)** - Psychological intent analysis and deception detection
529
606
  - **[Judge Guide](docs/apps/basic-judge.md)** - Text evaluation and scoring systems
607
+ - **[DeepSearch Guide](docs/apps/basic-deepsearch.md)** - Autonomous multi-stage research with web search
530
608
 
531
609
  **When to use the apps:**
532
610
  - Processing documents without writing code
@@ -605,6 +683,66 @@ summarizer document.pdf --provider anthropic --model claude-3-5-sonnet
605
683
 
606
684
  **Complete guide**: [Centralized Configuration](docs/centralized-config.md)
607
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
+
608
746
  ## Documentation
609
747
 
610
748
  **📚 Complete Documentation:** [docs/](docs/) - Full documentation index and navigation guide
@@ -772,6 +910,9 @@ pip install abstractcore[media]
772
910
  pip install abstractcore[openai]
773
911
  pip install abstractcore[anthropic]
774
912
  pip install abstractcore[ollama]
913
+ pip install abstractcore[lmstudio]
914
+ pip install abstractcore[huggingface]
915
+ pip install abstractcore[mlx] # macOS/Apple Silicon only
775
916
 
776
917
  # With server support
777
918
  pip install abstractcore[server]
@@ -781,6 +922,16 @@ pip install abstractcore[embeddings]
781
922
 
782
923
  # Everything (recommended)
783
924
  pip install abstractcore[all]
925
+
926
+ # Cross-platform (all except MLX - for Linux/Windows)
927
+ pip install abstractcore[all-non-mlx]
928
+
929
+ # Provider groups
930
+ pip install abstractcore[all-providers] # All providers (includes MLX)
931
+ pip install abstractcore[all-providers-non-mlx] # All providers except MLX
932
+ pip install abstractcore[local-providers] # Ollama, LMStudio, MLX
933
+ pip install abstractcore[local-providers-non-mlx] # Ollama, LMStudio only
934
+ pip install abstractcore[api-providers] # OpenAI, Anthropic
784
935
  ```
785
936
 
786
937
  **Media processing extras:**
@@ -811,6 +962,7 @@ All tests passing as of October 12th, 2025.
811
962
  ## Quick Links
812
963
 
813
964
  - **[📚 Documentation Index](docs/)** - Complete documentation navigation guide
965
+ - **[🔍 Interaction Tracing](docs/interaction-tracing.md)** - LLM observability and debugging ⭐ NEW
814
966
  - **[Getting Started](docs/getting-started.md)** - 5-minute quick start
815
967
  - **[⚙️ Prerequisites](docs/prerequisites.md)** - Provider setup (OpenAI, Anthropic, Ollama, etc.)
816
968
  - **[📖 Python API](docs/api-reference.md)** - Complete Python API reference
@@ -49,6 +49,9 @@ _has_processing = True
49
49
  # Tools module (core functionality)
50
50
  from .tools import tool
51
51
 
52
+ # Download module (core functionality)
53
+ from .download import download_model, DownloadProgress, DownloadStatus
54
+
52
55
  # Compression module (optional import)
53
56
  try:
54
57
  from .compression import GlyphConfig, CompressionOrchestrator
@@ -67,7 +70,10 @@ __all__ = [
67
70
  'ModelNotFoundError',
68
71
  'ProviderAPIError',
69
72
  'AuthenticationError',
70
- 'tool'
73
+ 'tool',
74
+ 'download_model',
75
+ 'DownloadProgress',
76
+ 'DownloadStatus',
71
77
  ]
72
78
 
73
79
  if _has_embeddings:
@@ -9,9 +9,9 @@ import json
9
9
  import os
10
10
  from typing import Dict, Any, Optional, List
11
11
  from pathlib import Path
12
- import logging
12
+ from ..utils.structured_logging import get_logger
13
13
 
14
- logger = logging.getLogger(__name__)
14
+ logger = get_logger(__name__)
15
15
 
16
16
  # Cache for loaded JSON data
17
17
  _architecture_formats: Optional[Dict[str, Any]] = None
@@ -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
@@ -8,13 +8,13 @@ and production LLM system requirements.
8
8
 
9
9
  import time
10
10
  import random
11
- import logging
12
11
  from typing import Type, Optional, Set, Dict, Any
13
12
  from dataclasses import dataclass
14
13
  from datetime import datetime, timedelta
15
14
  from enum import Enum
15
+ from ..utils.structured_logging import get_logger
16
16
 
17
- logger = logging.getLogger(__name__)
17
+ logger = get_logger(__name__)
18
18
 
19
19
 
20
20
  class RetryableErrorType(Enum):