abstractcore 2.4.5__tar.gz → 2.4.7__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.5 → abstractcore-2.4.7}/PKG-INFO +108 -12
- {abstractcore-2.4.5 → abstractcore-2.4.7}/README.md +98 -8
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/__init__.py +5 -1
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/assets/session_schema.json +1 -1
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/interface.py +7 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/session.py +28 -3
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/types.py +25 -1
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/anthropic_provider.py +20 -2
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/base.py +24 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/huggingface_provider.py +44 -18
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/lmstudio_provider.py +17 -4
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/mlx_provider.py +36 -14
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/mock_provider.py +17 -7
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/ollama_provider.py +16 -4
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/openai_provider.py +18 -5
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/common_tools.py +651 -1
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/version.py +1 -1
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/PKG-INFO +108 -12
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/SOURCES.txt +2 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/requires.txt +10 -3
- {abstractcore-2.4.5 → abstractcore-2.4.7}/pyproject.toml +11 -3
- abstractcore-2.4.7/tests/test_seed_determinism.py +354 -0
- abstractcore-2.4.7/tests/test_seed_temperature_basic.py +189 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/LICENSE +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/__main__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/app_config_utils.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/extractor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/judge.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/apps/summarizer.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/architectures/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/architectures/detection.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/architectures/enums.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/assets/architecture_formats.json +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/assets/model_capabilities.json +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/cli/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/cli/main.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/cli/vision_config.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/enums.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/factory.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/core/retry.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/embeddings/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/embeddings/manager.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/embeddings/models.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/events/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/exceptions/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/auto_handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/base.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/capabilities.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/handlers/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/handlers/anthropic_handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/handlers/local_handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/handlers/openai_handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/processors/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/processors/image_processor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/processors/office_processor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/processors/pdf_processor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/processors/text_processor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/types.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/utils/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/utils/image_scaler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/media/vision_fallback.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/processing/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/processing/basic_extractor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/processing/basic_judge.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/processing/basic_summarizer.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/registry.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/providers/streaming.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/server/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/server/app.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/structured/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/structured/handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/structured/retry.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/core.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/handler.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/parser.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/registry.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/syntax_rewriter.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/tools/tag_rewriter.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/__init__.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/cli.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/message_preprocessor.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/self_fixes.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/structured_logging.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore/utils/token_utils.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/dependency_links.txt +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/entry_points.txt +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/abstractcore.egg-info/top_level.txt +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/setup.cfg +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_agentic_cli_compatibility.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_all_specified_providers.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_basic_session.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_basic_summarizer.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_cli_media.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_complete_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_comprehensive_events.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_consistency.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_core_components.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_critical_streaming_tool_fix.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_debug_server.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_direct_vs_server.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_llm_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_matrix_operations.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_no_mock.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_real.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_semantic_validation.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_embeddings_simple.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_enhanced_prompt.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_environment_variable_tool_call_tags.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_factory.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_final_accuracy.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_final_comprehensive.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_final_graceful_errors.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_fixed_media.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_fixed_prompt.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_graceful_fallback.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_import_debug.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_integrated_functionality.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_lmstudio_context.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_media_import.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_media_server.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_ollama_tool_role_fix.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_openai_conversion_manual.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_openai_format_bug.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_openai_format_conversion.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_openai_media_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_progressive_complexity.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_basic_session.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_connectivity.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_simple_generation.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_streaming.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_token_translation.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_provider_tool_detection.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_providers.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_providers_comprehensive.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_providers_simple.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_real_models_comprehensive.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_retry_observability.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_retry_strategy.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_sensory_prompting.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_server_debug.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_server_embeddings_real.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_server_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_stream_tool_calling.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_streaming_enhancements.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_streaming_tag_rewriting.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_structured_integration.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_structured_output.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_syntax_rewriter.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_text_only_model_experience.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_tool_calling.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_tool_execution_separation.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_unified_streaming.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_unload_memory.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_user_scenario_validation.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_vision_accuracy.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_vision_comprehensive.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/tests/test_vision_fallback_improvement.py +0 -0
- {abstractcore-2.4.5 → abstractcore-2.4.7}/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.4.
|
|
3
|
+
Version: 2.4.7
|
|
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>
|
|
@@ -29,6 +29,7 @@ License-File: LICENSE
|
|
|
29
29
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
30
30
|
Requires-Dist: httpx<1.0.0,>=0.24.0
|
|
31
31
|
Requires-Dist: tiktoken<1.0.0,>=0.5.0
|
|
32
|
+
Requires-Dist: requests<3.0.0,>=2.25.0
|
|
32
33
|
Provides-Extra: openai
|
|
33
34
|
Requires-Dist: openai<2.0.0,>=1.0.0; extra == "openai"
|
|
34
35
|
Provides-Extra: anthropic
|
|
@@ -46,6 +47,11 @@ Provides-Extra: embeddings
|
|
|
46
47
|
Requires-Dist: sentence-transformers<4.0.0,>=2.7.0; extra == "embeddings"
|
|
47
48
|
Requires-Dist: numpy<2.0.0,>=1.20.0; extra == "embeddings"
|
|
48
49
|
Provides-Extra: processing
|
|
50
|
+
Provides-Extra: tools
|
|
51
|
+
Requires-Dist: beautifulsoup4<5.0.0,>=4.12.0; extra == "tools"
|
|
52
|
+
Requires-Dist: lxml<6.0.0,>=4.9.0; extra == "tools"
|
|
53
|
+
Requires-Dist: duckduckgo-search<4.0.0,>=3.8.0; extra == "tools"
|
|
54
|
+
Requires-Dist: psutil<6.0.0,>=5.9.0; extra == "tools"
|
|
49
55
|
Provides-Extra: media
|
|
50
56
|
Requires-Dist: Pillow<12.0.0,>=10.0.0; extra == "media"
|
|
51
57
|
Requires-Dist: pymupdf4llm<1.0.0,>=0.0.20; extra == "media"
|
|
@@ -60,9 +66,9 @@ Requires-Dist: abstractcore[huggingface]; extra == "heavy-providers"
|
|
|
60
66
|
Provides-Extra: all-providers
|
|
61
67
|
Requires-Dist: abstractcore[anthropic,embeddings,huggingface,lmstudio,mlx,ollama,openai]; extra == "all-providers"
|
|
62
68
|
Provides-Extra: all
|
|
63
|
-
Requires-Dist: abstractcore[anthropic,dev,docs,embeddings,huggingface,lmstudio,media,mlx,ollama,openai,processing,server,test]; extra == "all"
|
|
69
|
+
Requires-Dist: abstractcore[anthropic,dev,docs,embeddings,huggingface,lmstudio,media,mlx,ollama,openai,processing,server,test,tools]; extra == "all"
|
|
64
70
|
Provides-Extra: lightweight
|
|
65
|
-
Requires-Dist: abstractcore[anthropic,embeddings,lmstudio,media,ollama,openai,processing,server]; extra == "lightweight"
|
|
71
|
+
Requires-Dist: abstractcore[anthropic,embeddings,lmstudio,media,ollama,openai,processing,server,tools]; extra == "lightweight"
|
|
66
72
|
Provides-Extra: dev
|
|
67
73
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
68
74
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
@@ -89,7 +95,7 @@ Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
|
|
|
89
95
|
Requires-Dist: mkdocstrings[python]>=0.22.0; extra == "docs"
|
|
90
96
|
Requires-Dist: mkdocs-autorefs>=0.4.0; extra == "docs"
|
|
91
97
|
Provides-Extra: full-dev
|
|
92
|
-
Requires-Dist: abstractcore[all-providers,dev,docs,test]; extra == "full-dev"
|
|
98
|
+
Requires-Dist: abstractcore[all-providers,dev,docs,test,tools]; extra == "full-dev"
|
|
93
99
|
Dynamic: license-file
|
|
94
100
|
|
|
95
101
|
# AbstractCore
|
|
@@ -122,6 +128,21 @@ response = llm.generate("What is the capital of France?")
|
|
|
122
128
|
print(response.content)
|
|
123
129
|
```
|
|
124
130
|
|
|
131
|
+
### Deterministic Generation
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from abstractcore import create_llm
|
|
135
|
+
|
|
136
|
+
# Deterministic outputs with seed + temperature=0
|
|
137
|
+
llm = create_llm("openai", model="gpt-3.5-turbo", seed=42, temperature=0.0)
|
|
138
|
+
|
|
139
|
+
# These will produce identical outputs
|
|
140
|
+
response1 = llm.generate("Write exactly 3 words about coding")
|
|
141
|
+
response2 = llm.generate("Write exactly 3 words about coding")
|
|
142
|
+
print(f"Response 1: {response1.content}") # "Innovative, challenging, rewarding."
|
|
143
|
+
print(f"Response 2: {response2.content}") # "Innovative, challenging, rewarding."
|
|
144
|
+
```
|
|
145
|
+
|
|
125
146
|
### Tool Calling
|
|
126
147
|
|
|
127
148
|
```python
|
|
@@ -140,6 +161,78 @@ response = llm.generate(
|
|
|
140
161
|
print(response.content)
|
|
141
162
|
```
|
|
142
163
|
|
|
164
|
+
### Response Object (GenerateResponse)
|
|
165
|
+
|
|
166
|
+
Every LLM generation returns a **GenerateResponse** object with consistent structure across all providers:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from abstractcore import create_llm
|
|
170
|
+
|
|
171
|
+
llm = create_llm("openai", model="gpt-4o-mini")
|
|
172
|
+
response = llm.generate("Explain quantum computing in simple terms")
|
|
173
|
+
|
|
174
|
+
# Core response data
|
|
175
|
+
print(f"Content: {response.content}") # Generated text
|
|
176
|
+
print(f"Model: {response.model}") # Model used
|
|
177
|
+
print(f"Finish reason: {response.finish_reason}") # Why generation stopped
|
|
178
|
+
|
|
179
|
+
# Consistent token access across ALL providers (NEW in v2.4.7)
|
|
180
|
+
print(f"Input tokens: {response.input_tokens}") # Always available
|
|
181
|
+
print(f"Output tokens: {response.output_tokens}") # Always available
|
|
182
|
+
print(f"Total tokens: {response.total_tokens}") # Always available
|
|
183
|
+
|
|
184
|
+
# Generation time tracking (NEW in v2.4.7)
|
|
185
|
+
print(f"Generation time: {response.gen_time}ms") # Always available (rounded to 1 decimal)
|
|
186
|
+
|
|
187
|
+
# Advanced access
|
|
188
|
+
print(f"Tool calls: {response.tool_calls}") # Tools executed (if any)
|
|
189
|
+
print(f"Raw usage: {response.usage}") # Provider-specific token data
|
|
190
|
+
print(f"Metadata: {response.metadata}") # Additional context
|
|
191
|
+
|
|
192
|
+
# Comprehensive summary
|
|
193
|
+
print(f"Summary: {response.get_summary()}") # "Model: gpt-4o-mini | Tokens: 117 | Time: 1234.5ms"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Token Count Sources:**
|
|
197
|
+
- **Provider APIs**: OpenAI, Anthropic, LMStudio (native API token counts)
|
|
198
|
+
- **AbstractCore Calculation**: MLX, HuggingFace, Mock (using `token_utils.py`)
|
|
199
|
+
- **Mixed Sources**: Ollama (combination of provider and calculated tokens)
|
|
200
|
+
|
|
201
|
+
**Backward Compatibility**: Legacy `prompt_tokens` and `completion_tokens` keys remain available in `response.usage` dictionary.
|
|
202
|
+
|
|
203
|
+
### Built-in Tools
|
|
204
|
+
|
|
205
|
+
AbstractCore includes a comprehensive set of ready-to-use tools for common tasks:
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from abstractcore.tools.common_tools import fetch_url, search_files, read_file
|
|
209
|
+
|
|
210
|
+
# Intelligent web content fetching with automatic parsing
|
|
211
|
+
result = fetch_url("https://api.github.com/repos/python/cpython")
|
|
212
|
+
# Automatically detects JSON, HTML, images, PDFs, etc. and provides structured analysis
|
|
213
|
+
|
|
214
|
+
# File system operations
|
|
215
|
+
files = search_files("def.*fetch", ".", file_pattern="*.py") # Find function definitions
|
|
216
|
+
content = read_file("config.json") # Read file contents
|
|
217
|
+
|
|
218
|
+
# Use with any LLM
|
|
219
|
+
llm = create_llm("anthropic", model="claude-3-5-haiku-latest")
|
|
220
|
+
response = llm.generate(
|
|
221
|
+
"Analyze this API response and summarize the key information",
|
|
222
|
+
tools=[fetch_url]
|
|
223
|
+
)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Available Tools:**
|
|
227
|
+
- `fetch_url` - Intelligent web content fetching with automatic content type detection and parsing
|
|
228
|
+
- `search_files` - Search for text patterns inside files using regex
|
|
229
|
+
- `list_files` - Find and list files by names/paths using glob patterns
|
|
230
|
+
- `read_file` - Read file contents with optional line range selection
|
|
231
|
+
- `write_file` - Write content to files with directory creation
|
|
232
|
+
- `edit_file` - Edit files using pattern matching and replacement
|
|
233
|
+
- `web_search` - Search the web using DuckDuckGo
|
|
234
|
+
- `execute_command` - Execute shell commands safely with security controls
|
|
235
|
+
|
|
143
236
|
### Session Management
|
|
144
237
|
|
|
145
238
|
```python
|
|
@@ -223,19 +316,22 @@ response = llm.generate(
|
|
|
223
316
|
- **Session Management**: Persistent conversations with metadata, analytics, and complete serialization
|
|
224
317
|
- **Structured Responses**: Clean, predictable output formats with Pydantic
|
|
225
318
|
- **Streaming Support**: Real-time token generation for interactive experiences
|
|
319
|
+
- **Consistent Token Terminology**: Unified `input_tokens`, `output_tokens`, `total_tokens` across all providers
|
|
226
320
|
- **Embeddings**: Built-in support for semantic search and RAG applications
|
|
227
321
|
- **Universal Server**: Optional OpenAI-compatible API server with `/v1/responses` endpoint
|
|
228
322
|
|
|
229
323
|
## Supported Providers
|
|
230
324
|
|
|
231
|
-
| Provider | Status | Setup |
|
|
232
|
-
|
|
233
|
-
| **OpenAI** | Full | [Get API key](docs/prerequisites.md#openai-setup) |
|
|
234
|
-
| **Anthropic** | Full | [Get API key](docs/prerequisites.md#anthropic-setup) |
|
|
235
|
-
| **Ollama** | Full | [Install guide](docs/prerequisites.md#ollama-setup) |
|
|
236
|
-
| **LMStudio** | Full | [Install guide](docs/prerequisites.md#lmstudio-setup) |
|
|
237
|
-
| **MLX** | Full | [Setup guide](docs/prerequisites.md#mlx-setup) |
|
|
238
|
-
| **HuggingFace** | Full | [Setup guide](docs/prerequisites.md#huggingface-setup) |
|
|
325
|
+
| Provider | Status | SEED Support | Setup |
|
|
326
|
+
|----------|--------|-------------|-------|
|
|
327
|
+
| **OpenAI** | Full | ✅ Native | [Get API key](docs/prerequisites.md#openai-setup) |
|
|
328
|
+
| **Anthropic** | Full | ⚠️ Warning* | [Get API key](docs/prerequisites.md#anthropic-setup) |
|
|
329
|
+
| **Ollama** | Full | ✅ Native | [Install guide](docs/prerequisites.md#ollama-setup) |
|
|
330
|
+
| **LMStudio** | Full | ✅ Native | [Install guide](docs/prerequisites.md#lmstudio-setup) |
|
|
331
|
+
| **MLX** | Full | ✅ Native | [Setup guide](docs/prerequisites.md#mlx-setup) |
|
|
332
|
+
| **HuggingFace** | Full | ✅ Native | [Setup guide](docs/prerequisites.md#huggingface-setup) |
|
|
333
|
+
|
|
334
|
+
*Anthropic doesn't support seed parameters but issues a warning when provided. Use `temperature=0.0` for more consistent outputs.
|
|
239
335
|
|
|
240
336
|
## Server Mode (Optional HTTP REST API)
|
|
241
337
|
|
|
@@ -28,6 +28,21 @@ response = llm.generate("What is the capital of France?")
|
|
|
28
28
|
print(response.content)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
### Deterministic Generation
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from abstractcore import create_llm
|
|
35
|
+
|
|
36
|
+
# Deterministic outputs with seed + temperature=0
|
|
37
|
+
llm = create_llm("openai", model="gpt-3.5-turbo", seed=42, temperature=0.0)
|
|
38
|
+
|
|
39
|
+
# These will produce identical outputs
|
|
40
|
+
response1 = llm.generate("Write exactly 3 words about coding")
|
|
41
|
+
response2 = llm.generate("Write exactly 3 words about coding")
|
|
42
|
+
print(f"Response 1: {response1.content}") # "Innovative, challenging, rewarding."
|
|
43
|
+
print(f"Response 2: {response2.content}") # "Innovative, challenging, rewarding."
|
|
44
|
+
```
|
|
45
|
+
|
|
31
46
|
### Tool Calling
|
|
32
47
|
|
|
33
48
|
```python
|
|
@@ -46,6 +61,78 @@ response = llm.generate(
|
|
|
46
61
|
print(response.content)
|
|
47
62
|
```
|
|
48
63
|
|
|
64
|
+
### Response Object (GenerateResponse)
|
|
65
|
+
|
|
66
|
+
Every LLM generation returns a **GenerateResponse** object with consistent structure across all providers:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from abstractcore import create_llm
|
|
70
|
+
|
|
71
|
+
llm = create_llm("openai", model="gpt-4o-mini")
|
|
72
|
+
response = llm.generate("Explain quantum computing in simple terms")
|
|
73
|
+
|
|
74
|
+
# Core response data
|
|
75
|
+
print(f"Content: {response.content}") # Generated text
|
|
76
|
+
print(f"Model: {response.model}") # Model used
|
|
77
|
+
print(f"Finish reason: {response.finish_reason}") # Why generation stopped
|
|
78
|
+
|
|
79
|
+
# Consistent token access across ALL providers (NEW in v2.4.7)
|
|
80
|
+
print(f"Input tokens: {response.input_tokens}") # Always available
|
|
81
|
+
print(f"Output tokens: {response.output_tokens}") # Always available
|
|
82
|
+
print(f"Total tokens: {response.total_tokens}") # Always available
|
|
83
|
+
|
|
84
|
+
# Generation time tracking (NEW in v2.4.7)
|
|
85
|
+
print(f"Generation time: {response.gen_time}ms") # Always available (rounded to 1 decimal)
|
|
86
|
+
|
|
87
|
+
# Advanced access
|
|
88
|
+
print(f"Tool calls: {response.tool_calls}") # Tools executed (if any)
|
|
89
|
+
print(f"Raw usage: {response.usage}") # Provider-specific token data
|
|
90
|
+
print(f"Metadata: {response.metadata}") # Additional context
|
|
91
|
+
|
|
92
|
+
# Comprehensive summary
|
|
93
|
+
print(f"Summary: {response.get_summary()}") # "Model: gpt-4o-mini | Tokens: 117 | Time: 1234.5ms"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Token Count Sources:**
|
|
97
|
+
- **Provider APIs**: OpenAI, Anthropic, LMStudio (native API token counts)
|
|
98
|
+
- **AbstractCore Calculation**: MLX, HuggingFace, Mock (using `token_utils.py`)
|
|
99
|
+
- **Mixed Sources**: Ollama (combination of provider and calculated tokens)
|
|
100
|
+
|
|
101
|
+
**Backward Compatibility**: Legacy `prompt_tokens` and `completion_tokens` keys remain available in `response.usage` dictionary.
|
|
102
|
+
|
|
103
|
+
### Built-in Tools
|
|
104
|
+
|
|
105
|
+
AbstractCore includes a comprehensive set of ready-to-use tools for common tasks:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from abstractcore.tools.common_tools import fetch_url, search_files, read_file
|
|
109
|
+
|
|
110
|
+
# Intelligent web content fetching with automatic parsing
|
|
111
|
+
result = fetch_url("https://api.github.com/repos/python/cpython")
|
|
112
|
+
# Automatically detects JSON, HTML, images, PDFs, etc. and provides structured analysis
|
|
113
|
+
|
|
114
|
+
# File system operations
|
|
115
|
+
files = search_files("def.*fetch", ".", file_pattern="*.py") # Find function definitions
|
|
116
|
+
content = read_file("config.json") # Read file contents
|
|
117
|
+
|
|
118
|
+
# Use with any LLM
|
|
119
|
+
llm = create_llm("anthropic", model="claude-3-5-haiku-latest")
|
|
120
|
+
response = llm.generate(
|
|
121
|
+
"Analyze this API response and summarize the key information",
|
|
122
|
+
tools=[fetch_url]
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Available Tools:**
|
|
127
|
+
- `fetch_url` - Intelligent web content fetching with automatic content type detection and parsing
|
|
128
|
+
- `search_files` - Search for text patterns inside files using regex
|
|
129
|
+
- `list_files` - Find and list files by names/paths using glob patterns
|
|
130
|
+
- `read_file` - Read file contents with optional line range selection
|
|
131
|
+
- `write_file` - Write content to files with directory creation
|
|
132
|
+
- `edit_file` - Edit files using pattern matching and replacement
|
|
133
|
+
- `web_search` - Search the web using DuckDuckGo
|
|
134
|
+
- `execute_command` - Execute shell commands safely with security controls
|
|
135
|
+
|
|
49
136
|
### Session Management
|
|
50
137
|
|
|
51
138
|
```python
|
|
@@ -129,19 +216,22 @@ response = llm.generate(
|
|
|
129
216
|
- **Session Management**: Persistent conversations with metadata, analytics, and complete serialization
|
|
130
217
|
- **Structured Responses**: Clean, predictable output formats with Pydantic
|
|
131
218
|
- **Streaming Support**: Real-time token generation for interactive experiences
|
|
219
|
+
- **Consistent Token Terminology**: Unified `input_tokens`, `output_tokens`, `total_tokens` across all providers
|
|
132
220
|
- **Embeddings**: Built-in support for semantic search and RAG applications
|
|
133
221
|
- **Universal Server**: Optional OpenAI-compatible API server with `/v1/responses` endpoint
|
|
134
222
|
|
|
135
223
|
## Supported Providers
|
|
136
224
|
|
|
137
|
-
| Provider | Status | Setup |
|
|
138
|
-
|
|
139
|
-
| **OpenAI** | Full | [Get API key](docs/prerequisites.md#openai-setup) |
|
|
140
|
-
| **Anthropic** | Full | [Get API key](docs/prerequisites.md#anthropic-setup) |
|
|
141
|
-
| **Ollama** | Full | [Install guide](docs/prerequisites.md#ollama-setup) |
|
|
142
|
-
| **LMStudio** | Full | [Install guide](docs/prerequisites.md#lmstudio-setup) |
|
|
143
|
-
| **MLX** | Full | [Setup guide](docs/prerequisites.md#mlx-setup) |
|
|
144
|
-
| **HuggingFace** | Full | [Setup guide](docs/prerequisites.md#huggingface-setup) |
|
|
225
|
+
| Provider | Status | SEED Support | Setup |
|
|
226
|
+
|----------|--------|-------------|-------|
|
|
227
|
+
| **OpenAI** | Full | ✅ Native | [Get API key](docs/prerequisites.md#openai-setup) |
|
|
228
|
+
| **Anthropic** | Full | ⚠️ Warning* | [Get API key](docs/prerequisites.md#anthropic-setup) |
|
|
229
|
+
| **Ollama** | Full | ✅ Native | [Install guide](docs/prerequisites.md#ollama-setup) |
|
|
230
|
+
| **LMStudio** | Full | ✅ Native | [Install guide](docs/prerequisites.md#lmstudio-setup) |
|
|
231
|
+
| **MLX** | Full | ✅ Native | [Setup guide](docs/prerequisites.md#mlx-setup) |
|
|
232
|
+
| **HuggingFace** | Full | ✅ Native | [Setup guide](docs/prerequisites.md#huggingface-setup) |
|
|
233
|
+
|
|
234
|
+
*Anthropic doesn't support seed parameters but issues a warning when provided. Use `temperature=0.0` for more consistent outputs.
|
|
145
235
|
|
|
146
236
|
## Server Mode (Optional HTTP REST API)
|
|
147
237
|
|
|
@@ -44,6 +44,9 @@ except ImportError:
|
|
|
44
44
|
from .processing import BasicSummarizer, SummaryStyle, SummaryLength, BasicExtractor
|
|
45
45
|
_has_processing = True
|
|
46
46
|
|
|
47
|
+
# Tools module (core functionality)
|
|
48
|
+
from .tools import tool
|
|
49
|
+
|
|
47
50
|
__all__ = [
|
|
48
51
|
'create_llm',
|
|
49
52
|
'BasicSession',
|
|
@@ -54,7 +57,8 @@ __all__ = [
|
|
|
54
57
|
'MessageRole',
|
|
55
58
|
'ModelNotFoundError',
|
|
56
59
|
'ProviderAPIError',
|
|
57
|
-
'AuthenticationError'
|
|
60
|
+
'AuthenticationError',
|
|
61
|
+
'tool'
|
|
58
62
|
]
|
|
59
63
|
|
|
60
64
|
if _has_embeddings:
|
|
@@ -70,6 +70,8 @@ class AbstractCoreInterface(ABC):
|
|
|
70
70
|
max_tokens: Optional[int] = None,
|
|
71
71
|
max_input_tokens: Optional[int] = None,
|
|
72
72
|
max_output_tokens: int = 2048,
|
|
73
|
+
temperature: float = 0.7,
|
|
74
|
+
seed: Optional[int] = None,
|
|
73
75
|
debug: bool = False,
|
|
74
76
|
**kwargs):
|
|
75
77
|
self.model = model
|
|
@@ -79,6 +81,11 @@ class AbstractCoreInterface(ABC):
|
|
|
79
81
|
self.max_tokens = max_tokens
|
|
80
82
|
self.max_input_tokens = max_input_tokens
|
|
81
83
|
self.max_output_tokens = max_output_tokens
|
|
84
|
+
|
|
85
|
+
# Unified generation parameters
|
|
86
|
+
self.temperature = temperature
|
|
87
|
+
self.seed = seed
|
|
88
|
+
|
|
82
89
|
self.debug = debug
|
|
83
90
|
|
|
84
91
|
# Validate token parameters
|
|
@@ -32,8 +32,23 @@ class BasicSession:
|
|
|
32
32
|
tool_timeout: Optional[float] = None,
|
|
33
33
|
recovery_timeout: Optional[float] = None,
|
|
34
34
|
auto_compact: bool = False,
|
|
35
|
-
auto_compact_threshold: int = 6000
|
|
36
|
-
|
|
35
|
+
auto_compact_threshold: int = 6000,
|
|
36
|
+
temperature: Optional[float] = None,
|
|
37
|
+
seed: Optional[int] = None):
|
|
38
|
+
"""Initialize basic session
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
provider: LLM provider instance
|
|
42
|
+
system_prompt: System prompt for the session
|
|
43
|
+
tools: List of available tools
|
|
44
|
+
timeout: HTTP request timeout
|
|
45
|
+
tool_timeout: Tool execution timeout
|
|
46
|
+
recovery_timeout: Circuit breaker recovery timeout
|
|
47
|
+
auto_compact: Enable automatic conversation compaction
|
|
48
|
+
auto_compact_threshold: Token threshold for auto-compaction
|
|
49
|
+
temperature: Default temperature for generation (0.0-1.0)
|
|
50
|
+
seed: Default seed for deterministic generation
|
|
51
|
+
"""
|
|
37
52
|
|
|
38
53
|
self.provider = provider
|
|
39
54
|
self.id = str(uuid.uuid4())
|
|
@@ -45,6 +60,10 @@ class BasicSession:
|
|
|
45
60
|
self.auto_compact_threshold = auto_compact_threshold
|
|
46
61
|
self._original_session = None # Track if this is a compacted session
|
|
47
62
|
|
|
63
|
+
# Store session-level generation parameters
|
|
64
|
+
self.temperature = temperature
|
|
65
|
+
self.seed = seed
|
|
66
|
+
|
|
48
67
|
# Optional analytics fields
|
|
49
68
|
self.summary = None
|
|
50
69
|
self.assessment = None
|
|
@@ -189,6 +208,12 @@ class BasicSession:
|
|
|
189
208
|
# Extract media parameter explicitly (fix for media parameter passing)
|
|
190
209
|
media = kwargs.pop('media', None)
|
|
191
210
|
|
|
211
|
+
# Add session-level parameters if not overridden in kwargs
|
|
212
|
+
if 'temperature' not in kwargs and self.temperature is not None:
|
|
213
|
+
kwargs['temperature'] = self.temperature
|
|
214
|
+
if 'seed' not in kwargs and self.seed is not None:
|
|
215
|
+
kwargs['seed'] = self.seed
|
|
216
|
+
|
|
192
217
|
# Call provider
|
|
193
218
|
response = self.provider.generate(
|
|
194
219
|
prompt=prompt,
|
|
@@ -735,7 +760,7 @@ class BasicSession:
|
|
|
735
760
|
"tokens_before": original_tokens,
|
|
736
761
|
"tokens_after": self._estimate_tokens_for_summary(summary_result.summary),
|
|
737
762
|
"compression_ratio": self._calculate_compression_ratio(original_tokens, summary_result.summary),
|
|
738
|
-
"
|
|
763
|
+
"gen_time": duration_ms
|
|
739
764
|
}
|
|
740
765
|
}
|
|
741
766
|
|
|
@@ -91,6 +91,7 @@ class GenerateResponse:
|
|
|
91
91
|
usage: Optional[Dict[str, int]] = None
|
|
92
92
|
tool_calls: Optional[List[Dict[str, Any]]] = None
|
|
93
93
|
metadata: Optional[Dict[str, Any]] = None
|
|
94
|
+
gen_time: Optional[float] = None # Generation time in milliseconds
|
|
94
95
|
|
|
95
96
|
def has_tool_calls(self) -> bool:
|
|
96
97
|
"""Check if response contains tool calls"""
|
|
@@ -109,6 +110,29 @@ class GenerateResponse:
|
|
|
109
110
|
parts.append(f"Model: {self.model}")
|
|
110
111
|
if self.usage:
|
|
111
112
|
parts.append(f"Tokens: {self.usage.get('total_tokens', 'unknown')}")
|
|
113
|
+
if self.gen_time:
|
|
114
|
+
parts.append(f"Time: {self.gen_time:.1f}ms")
|
|
112
115
|
if self.tool_calls:
|
|
113
116
|
parts.append(f"Tools: {len(self.tool_calls)} executed")
|
|
114
|
-
return " | ".join(parts)
|
|
117
|
+
return " | ".join(parts)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def input_tokens(self) -> Optional[int]:
|
|
121
|
+
"""Get input tokens with consistent terminology (prompt_tokens or input_tokens)."""
|
|
122
|
+
if not self.usage:
|
|
123
|
+
return None
|
|
124
|
+
return self.usage.get('input_tokens') or self.usage.get('prompt_tokens')
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def output_tokens(self) -> Optional[int]:
|
|
128
|
+
"""Get output tokens with consistent terminology (completion_tokens or output_tokens)."""
|
|
129
|
+
if not self.usage:
|
|
130
|
+
return None
|
|
131
|
+
return self.usage.get('output_tokens') or self.usage.get('completion_tokens')
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def total_tokens(self) -> Optional[int]:
|
|
135
|
+
"""Get total tokens."""
|
|
136
|
+
if not self.usage:
|
|
137
|
+
return None
|
|
138
|
+
return self.usage.get('total_tokens')
|
|
@@ -47,8 +47,7 @@ class AnthropicProvider(BaseProvider):
|
|
|
47
47
|
# Initialize tool handler
|
|
48
48
|
self.tool_handler = UniversalToolHandler(model)
|
|
49
49
|
|
|
50
|
-
# Store configuration
|
|
51
|
-
self.temperature = kwargs.get("temperature", 0.7)
|
|
50
|
+
# Store provider-specific configuration
|
|
52
51
|
self.top_p = kwargs.get("top_p", 1.0)
|
|
53
52
|
self.top_k = kwargs.get("top_k", None)
|
|
54
53
|
|
|
@@ -132,6 +131,19 @@ class AnthropicProvider(BaseProvider):
|
|
|
132
131
|
if kwargs.get("top_k") or self.top_k:
|
|
133
132
|
call_params["top_k"] = kwargs.get("top_k", self.top_k)
|
|
134
133
|
|
|
134
|
+
# Handle seed parameter (Anthropic doesn't support seed natively)
|
|
135
|
+
seed_value = kwargs.get("seed", self.seed)
|
|
136
|
+
if seed_value is not None:
|
|
137
|
+
import warnings
|
|
138
|
+
warnings.warn(
|
|
139
|
+
f"Seed parameter ({seed_value}) is not supported by Anthropic Claude API. "
|
|
140
|
+
f"For deterministic outputs, use temperature=0.0 which may provide more consistent results, "
|
|
141
|
+
f"though true determinism is not guaranteed.",
|
|
142
|
+
UserWarning,
|
|
143
|
+
stacklevel=3
|
|
144
|
+
)
|
|
145
|
+
self.logger.warning(f"Seed {seed_value} requested but not supported by Anthropic API")
|
|
146
|
+
|
|
135
147
|
# Handle structured output using the "tool trick"
|
|
136
148
|
structured_tool_name = None
|
|
137
149
|
if response_model and PYDANTIC_AVAILABLE:
|
|
@@ -174,8 +186,14 @@ class AnthropicProvider(BaseProvider):
|
|
|
174
186
|
if stream:
|
|
175
187
|
return self._stream_response(call_params, tools)
|
|
176
188
|
else:
|
|
189
|
+
# Track generation time
|
|
190
|
+
start_time = time.time()
|
|
177
191
|
response = self.client.messages.create(**call_params)
|
|
192
|
+
gen_time = round((time.time() - start_time) * 1000, 1)
|
|
193
|
+
|
|
178
194
|
formatted = self._format_response(response)
|
|
195
|
+
# Add generation time to response
|
|
196
|
+
formatted.gen_time = gen_time
|
|
179
197
|
|
|
180
198
|
# Handle tool execution for Anthropic responses
|
|
181
199
|
if tools and (formatted.has_tool_calls() or
|
|
@@ -570,8 +570,32 @@ class BaseProvider(AbstractCoreInterface, ABC):
|
|
|
570
570
|
result_kwargs = kwargs.copy()
|
|
571
571
|
result_kwargs["max_output_tokens"] = effective_max_output
|
|
572
572
|
|
|
573
|
+
# Add unified generation parameters with fallback hierarchy: kwargs → instance → defaults
|
|
574
|
+
result_kwargs["temperature"] = result_kwargs.get("temperature", self.temperature)
|
|
575
|
+
if self.seed is not None:
|
|
576
|
+
result_kwargs["seed"] = result_kwargs.get("seed", self.seed)
|
|
577
|
+
|
|
573
578
|
return result_kwargs
|
|
574
579
|
|
|
580
|
+
def _extract_generation_params(self, **kwargs) -> Dict[str, Any]:
|
|
581
|
+
"""
|
|
582
|
+
Extract generation parameters with consistent fallback hierarchy.
|
|
583
|
+
|
|
584
|
+
Returns:
|
|
585
|
+
Dict containing temperature, seed, and other generation parameters
|
|
586
|
+
"""
|
|
587
|
+
params = {}
|
|
588
|
+
|
|
589
|
+
# Temperature (always present)
|
|
590
|
+
params["temperature"] = kwargs.get("temperature", self.temperature)
|
|
591
|
+
|
|
592
|
+
# Seed (only if not None)
|
|
593
|
+
seed_value = kwargs.get("seed", self.seed)
|
|
594
|
+
if seed_value is not None:
|
|
595
|
+
params["seed"] = seed_value
|
|
596
|
+
|
|
597
|
+
return params
|
|
598
|
+
|
|
575
599
|
def _get_provider_max_tokens_param(self, kwargs: Dict[str, Any]) -> int:
|
|
576
600
|
"""
|
|
577
601
|
Extract the appropriate max tokens parameter for this provider.
|